Friday, February 23, 2018

Changing a BPEL process' interface definition from asynchronous to synchronous (and vice versa)


So it happened to me before that during development I came to realize that my BPEL process should have been designed as synchronous in the first place instead of having an asynchronous definition. When you were already well under way developing you're not really keen on throwing your work away and start all over. Well the good news is that you don't have to. It's actually quite easy to transform your BPEL process from an asynchronous into a synchronous interface. It even works the other way around. I'll demonstrate how.

So this is what we're talking about. When you start off you used the asynchronous BPEL process template.


With hindsight, you wanted to use the synchronous BPEL process template.


Now to change the interface definition we will have to make alterations in three files:
 - The composite.xml
 - The .bpel file
 - The WSDL 

1. The composite.xml
Look for the interface.wsdl tag and remove the yellow part. If you need to convert your BPEL from synchronous to asynchronous, add the yellow part.
<interface.wsdl interface="http://xmlns.oracle.com/WCC_Orchestration_BPELapp/SampleProject/SampleProjectBpel#wsdl.interface(SampleProjectBpel)" callbackInterface="http://xmlns.oracle.com/WCC_Orchestration_BPELapp/SampleProject/SampleProjectBpel#wsdl.interface(SampleProjectBpelCallback)"/>

Look for the callback tag and remove the yellow part. If you need to convert your BPEL from synchronous to asynchronous, add the yellow part within the <service></service> tags.
<callback>
<binding.ws port="http://xmlns.oracle.com/WCC_Orchestration_BPELapp/SampleProject/SampleProjectBpel#wsdl.endpoint(sampleprojectbpel_client_ep/SampleProjectBpelCallback_pt)"/>
</callback>

Look for the componentType tag and remove the yellow part. If you need to convert your BPEL from synchronous to asynchronous, add the yellow part.
<componentType>
<service name="sampleprojectbpel_client" ui:wsdlLocation="WSDLs/SampleProjectBpel.wsdl">
<interface.wsdl interface="http://xmlns.oracle.com/WCC_Orchestration_BPELapp/SampleProject/SampleProjectBpel#wsdl.interface(SampleProjectBpel)"
 callbackInterface="http://xmlns.oracle.com/WCC_Orchestration_BPELapp/SampleProject/SampleProjectBpel#wsdl.interface(SampleProjectBpelCallback)"/>
</service>
</componentType>

Look for the following property:
<property name="bpel.config.oneWayDeliveryPolicy" type="xs:string" many="false">async.persist</property>
Change it to:
<property name="bpel.config.transaction" type="xs:string" many="false">required</property>
If you need to convert your BPEL from synchronous to asynchronous, replace the blue with the yellow parts.

2. The .bpel file
Look for the partnerlink tag and remove the yellow part.
If you need to convert your BPEL from synchronous to asynchronous, add the yellow part.
<partnerLink name="sampleprojectbpel_client" partnerLinkType="client:SampleProjectBpel" myRole="SampleProjectBpelProvider" partnerRole="SampleProjectBpelRequester"/>

Look for the invoke construct:
<invoke name="callbackClient" partnerLink="sampleprojectbpel_client" portType="client:SampleProjectBpelCallback" operation="processResponse" inputVariable="outputVariable"/>
Change it to:
<reply name="replyOutput" partnerLink="sampleprojectbpel_client" portType="client:SampleProjectBpel" operation="process" variable="outputVariable"/>
If you need to convert your BPEL from synchronous to asynchronous, replace the blue with the yellow parts.

3. The WSDL 
Look for the portType tag that contains the Callback and remove it.
If you need to convert your BPEL from synchronous to asynchronous, add it.
<wsdl:portType name="SampleProjectBpelCallback">
   <wsdl:operation name="processResponse">
       <wsdl:input message="client:SampleProjectBpelResponseMessage"/>
    </wsdl:operation>
</wsdl:portType> 

Now look for the other portType tag and add the yellow part to set the output message.
If you need to convert your BPEL from synchronous to asynchronous, delete it.
<wsdl:portType name="SampleProjectBpel">
    <wsdl:operation name="process">
       <wsdl:input message="client:SampleProjectBpelRequestMessage"/>
       <wsdl:output message="client:SampleProjectBpelResponseMessage"/>
    </wsdl:operation>
</wsdl:portType>

Look for the partnerLinkType tag and delete the yellow part.
If you need to convert your BPEL from synchronous to asynchronous, add it.
<plnk:partnerLinkType name="SampleProjectBpel">
      <plnk:role name="SampleProjectBpelProvider" portType="client:SampleProjectBpel"/>
      <plnk:role name="SampleProjectBpelRequester" portType="client:SampleProjectBpelCallback"/>
</plnk:partnerLinkType>

That's all!

Friday, February 16, 2018

A simple example of the for-each functionality

A component that I frequently use in my BPEL processes is the for-each component. It's an easy feature to loop through data, assert data to a variable and do multiple service calls. I will show you a simple example of how the for-each component can be used. Suppose we retrieve a list of folder ID's and for each of these we will do a service call which returns additional data about those folders. This data will be asserted altogether so we can do some data transformation later in our BPEL process.

So this is the list of folders we are working with and is stored in a variable. We want to call a service that retrieves additional data about the FOLDERGUIDs.
 
The for-each part of our BPEL process looks like this:

After dragging the for-each component to our canvas we can edit the conditions. We can give our for-each loop a name. In this case I just called it 'ForEach'. The for-each has a counter variable that keeps track of the index of loops. Here I named the counter variable 'ForEachCounter'.
Next we define the start and final value of our counter. Here the counter starts with index 1. The final value of the counter is determined by the number of FOLDERGUIDs I have in my list. That's why I used the count function that will calculate the occurences of FOLDERGUIDS in the variable that holds the list.
In the tab 'Completion' you could enter an expression that will determine when to exit the for-each loop. For example when a certain condition is met it would not be necessary anymore to proceed with the loop.
Next we want to provide the element FOLDERGUID from our list to be the input parameter to call the service that retrieves additional data about our folders. When we assign the FOLDERGUID as the input parameter we have to keep the counter in mind that keeps track of the position of our FOLDERGUIDS. That's why we put [$ForEachCounter] in our expression.
The data returned could be asserted to a new variable for further transformation.

And that's it basically! Here I have demonstrated a common use of the for-each function in BPEL. 

Hello world!

Let me introduce myself. My Name is Ling and I have been working as an Oracle middleware consultant for a few years now. Products and technologies I have worked with amongst others are OSB, ADF, WCC and recently I started exploring the world of SOA Suite. This blog will mostly act as a personal notebook for tips and tricks I come across but I'm happy to share it with the world as it might help someone out!