Saturday, March 22, 2008

Changing an Asynchronous Oracle BPEL process to be Synchronous

One of the top suggestions Oracle has for tuning BPEL processes is to make sure that processes that can be synchronous are. This is because synchronous processes can be considered transient within the BPEL engine -- and the BPEL engine has several tunable parameters for transient processes that determine if and when they are pushed to the dehydration store. Fewer dehydration trips means better performance.

An obvious question then becomes "I just created a bunch of BPEL processes and they are all asynchronous, do I have to recreate them?" The short answer is: NO!

If you take a look at an asynchronous process, you'll notice that the last step is typically a callback client, while for a synchronous process it is a reply. This is because the client of a synchronous process is blocking during the call and a simple reply response is made to that blocked client. An asynchronous process makes a callback to the non-blocking client using the partner link (although of using a different partnerLinkType).

To start modifying your process, open the process .bpel file in design mode using JDeveloper. Delete the callback client step at the end of the process, this will be an invoke block connected back to the client. Drag a new reply block to that space. Now connect the reply block to the client partner link. You should change the reply name to "replyOutput" or something similarly useful.

Next, we need to make some further changes to the process .bpel file, so switch to source view. Scroll down the file until you come to the sequence element. Find the receive and reply elements within the sequence and change the operation attribute value of each one to "process". You will also need to add variable attribute to the reply element. Set this to the value of the output variable - by default this would be "outputVariable". Sample receive and reply elements look like this:


<receive name="receiveInput" partnerLink="client"
portType="client:BPELProcess2" operation="process"
variable="inputVariable" createInstance="yes"/>


<reply name="replyOutput" partnerLink="client"
portType="client:BPELProcess2" operation="process"
variable="outputVariable"/>


For the last changes, you need to open up your process' .wsdl file in the source editor. The WSDL edits are a bit more involved so, follow closely....

First, find the two portType definitions. One of them, typically the second one, should have the name attribute set to something like <yourprocessname>Callback and the operation set to "onResult". Copy the input element and paste it under the existing input element in the first portType definition. Change the element you just copied from "input" to "output". Change the operation name of this portType to "process".

Going back to the Callback portType, delete the entire portType definition. If you'd rather you can simply comment it out.

Now find a the partnerLinkType element. You'll want to delete the plnk:role element within that has the same portType name attribute as the portType you just deleted. Make sure you remove the entire plnk:role element and not just the plnk:portType.

Here is an excerpt of my changed WSDL, with comments where I made changes:


<portType name="BPELProcess2">
<operation name="process">
<input message="client:BPELProcess2RequestMessage"/>
<!-- copied from old call back, change input to output -->
<output message="client:BPELProcess2ResponseMessage"/>
</operation>
</portType>

<!-- removed/comment out to make synchronous
<portType name="BPELProcess2Callback">
<operation name="onResult">
<input message="client:BPELProcess2ResponseMessage"/>
</operation>
</portType>
-->

<plnk:partnerLinkType name="BPELProcess2">
<plnk:role name="BPELProcess2Provider">
<plnk:portType name="client:BPELProcess2"/>
</plnk:role>

<!-- remove/comment out to make synchronous
<plnk:role name="BPELProcess2Requester">
<plnk:portType name="client:BPELProcess2Callback"/>
</plnk:role>
-->

</plnk:partnerLinkType>


You should now be able to save your changes and recompile the project -- see that was easy wasn't it?

1 comment:

Unknown said...

Thanks for posting this little tutorial. It helped me quite a bit.