Oracle SOA, AIA BPEL ESB and OSB knowledge base

Monday, March 23, 2009

Oracle Service Bus : Split Join Example

Thanks to Edwin to highlight this feature.

One of the cool features of the OSB is Split-Join feature with this you can split up you service request message and process these parts parallel. This part can be processed in an other service. The results or errors of these parts will be later joined together and send back in the response of the proxy service. In this blog I will use a Web Service which has as input Orders and we will split these orders to one order. Because I don't know how many orders I can receive we need to use a Dynamic Split-Join.

This is the xsd I used

I created a WSDL with operation which has a request and a response based on the xsd above

Create a new Split-Join ( You have to do this from the workshop application) where we select the operation of the just created wsdl
The Split-Join automatically creates two variables.

We have to initialize the response variable by adding an assign action where I add the result element to the response variable. Put this Assign action right after Receive
Now we can add a For Each Flow Control which will handle every Order, Put this after the Assign Action.

Select the For Each component where we can define the parallel mode of the order processing and we have to define the counter variable name which start in my case with 1 and ends with the count of the order elements.
Add a new variable order which is based on the order element. We will copy later one order to this variable.
Add a copy action to the Scope window of the For Each component where we use the counter variable to get the right order and pass this value to the order variable. (
$request.parameters/def:Orders/def:Order[$counter] )
Let's change the status of a order by adding a new copy action. Normally you will call an external service which processes the order and returns the result.
Now we collect the result of an order and this to the right place in the responce variable.
A Split-Join can only be called from a business service so let's create one automatically.


This business can be called by a proxy service. Create a proxy service based on the same WSDL as the split-join.
Add some routing to this proxy so the split-join business service is called from this proxy service
Publish this project to the ESB where we can test the proxy service. OSB automatically generates a example orders xml where we will add an extra order.
And voila here is the response where the status element value of the orders are changed to processed.

Dynamic transformations using Oracle Service Bus

Dynamic transformations using Oracle Service Bus

Thanks to Chris for making it very clear.

One of the new features in Oracle Service Bus 10gR3, and one commonly requested by customers, is the ability to choose the transformation to apply to a message based on runtime information - also known as dynamic transformations.

In the previous version of Oracle Service Bus you could only specify the transformation to be performed on the message at design time which may have resulted in:

- Multiple proxy services performing the same mediation logic, but applying different transformations

- A proxy service message flow containing a for loop with a number of cases each performing a different transformation

These scenarios can easily be handled when the number of transformations is small and/or doesn't change regularly but both scenarios involve modifying or creating a proxy service just to add a new transformation. Dynamic transformations allow you to define a proxy service which can handle new transformations being added at a later date.

Let's look at how we might implement a typical scenario where a proxy service accepts multiple versions of a message and applies an appropriate transformation based on the version of the message (determined by the namespace of the root element) in order to convert the message into a common format.

First create a new Oracle Service Bus project called DynamicTransformation (File>New>Oracle Service Bus Project, enter a name of DynamicTransformation and click Finish)

Then create a new schema file called Customer.xsd (File>New>Other>XML Schema) and define the common format with the target namespace http://www.oracle.com/Customer and the following structure:

customer_common_format

Now define a CustomerApplication business service which accepts messages in this format (File>New>Business Service, enter a name of CustomerApplication and click Finish)

Now in the main editor pane, select the General tab for this service and make sure it is defined as a Messaging Service.

Now move to the Messaging tab, set the Request Type to XML and click the Browse button to select the Customer element from Customer.xsd as the message format definition:

Now move to the Transport tab:

- Select the protocol as JMS

- Click Add to accept the default URL or modify it to point to a valid JMS endpoint

(NB. You will need to ensure the connection factory and queue specified in this JMS endpoint exist. If you accept the default, and are running on the default port of 7001 you should only need to create a JMS queue with a JNDI name of CustomerApplicationRequest on the WebLogic Server instance underpinning your Service Bus instance as the connection factory is created for you).

Now move to the JMS Transport tab:

- Select the Message Type as Text and leave the other values as their defaults.

Now test this business service is working as expected by right clicking on it in the Project Explorer and selecting Run As. When the Select Tasks dialog box appears, just click Finish. This should launch the Test Console.

Enter some sample data (the Test Console should have generated the structure for you) and then click Execute.

business_service_testing_customer_application

This should succeed but without a response (this is a one way service and the message has been placed on the CustomerApplicationRequest queue). Navigate to the CustomerApplicationJMS queue and check it contains your message:

customer_application_request

Next create a new schema file called CustomerV1.xsd and define the CustomerV1 format to be in the http://www.oracle.com/CustomerV1 target namespace and have the following structure:

customer_v1

And one called CustomerV2.xsd defining our CustomerV2 format to be in the http://www.oracle.com/CustomerV2 target namespace and have the following structure:

customer_v2

Next, lets create our transformations: Version1.xq (which converts from CustomerV1 format to the common Customer format):

Version1

And Version2.xq (which converts from Customer V2 format to the common Customer format):

Version2

NB. It is important the target namespaces and transformation filenames are named as described as this is how the correct transformation is selected.

So now we have our transformations and formats defined, the final step is to create our Customer proxy service (File>New>Proxy Service, enter name Customer and click Finish) which will actually perform the dynamic transformation.

In the General tab, select the Service Type to be Messaging Service.

In the Messaging tab, select the Request Type to be XML but don't specify a format (this is because this service can accept both V1 and V2 message formats).

In the Transport tab, select the Protocol to be JMS and accept the default endpoint (the queue and connection factory pointed at by this JMS endpoint will be created for you).

In the Message Flow tab create a message flow like the following which routes to the CustomerApplication business service:

dynamic_transformation_message_fllow

The Assign action extracts the version number (the last digit) from the namespace URI for the Customer element and stores it in the version variable:

assign_properties

NB. The XPath expression here gets the namespace URI of the Customer element (fn:namespace-uri), converts it into a string (fn:string) and then extracts the version number from the end of the string (fn:substring-after).

The Replace action replaces the entire contents of the body with the result of performing the XQuery transformation, the name of which is determined, in this case, by concatenating the static string DynamicTransformation/Version with the value stored in the version variable:

replace_properties

In order to create the Expression line you need to have clicked in the Expression field and completed the XQuery editor as follows:

xquery_expression_editor

The Bind Variables field defines the variable passed to the transformation. To create this simply enter the name Customer in the Add Custom Variable field and clicked Add. The XPath expression here evaluates to the Customer element within the body, irrespective of namespace.

After completing this, save everything and then launch the Test Console on the Customer proxy service (right click on it and select Run As).

Enter a CustomerV1 format message into the payload field (you can generate a sample one of these by right clicking on CustomerV1.xsd in Workshop and selecting Generate XML).

Then click Execute.

The invocation should succeed without a response - the V1 message should have been transformed to the common Customer format, the CustomerApplication business service invoked and a common Customer format message placed on the CustomerApplicationRequest JMS queue. Check the JMS queue to see this is the case.

Then try the same, but replace the payload with a CustomerV2 format message. This should also succeed without a response - the V2 message having been also transformed to the common Customer format and placed on the CustomerApplicationRequest JMS queue. Again, check the JMS queue to see that this is the case.

That's it. You've just implemented your first dynamic transformation with Oracle Service Bus - congratulations!

NB. A few words of caution when adopting an approach like the one described above. Since your proxy service now has a weakly defined service contract rather than a strongly defined one you will need to describe to your service consumers the message structure(s) your service supports (probably via documentation) and also ensure you have some error handling to deal with unsupported message formats.


Monday, March 2, 2009

Calling OSB services from BPEL

Calling OSB services from BPEL

In my previous blog I already talked about calling BPEL services
from OSB. In this blog entry I will show you how to call an synchronous OSB proxy service from BPEL. If you have problems to get this working, please see my previous blog entry how to solve this. I got this working with OSB 10.3 and Soa Suite 10.1.3.4 MLR5.
First we need to have an OSB proxy service with an WSDL.
As transport protocol we will use the SB protocol
Export the WSDL of the OSB Proxy service and put the wsdl and xsd's in your BPEL project.

When we take a look at the WSDL we can see that the OSB proxy service address is sb://xxx:70001/w..

In the BPEL project we can add a partnerlink, where we will use the OSB proxy wsdl.

Next step is to add an invoke process activity where we can select the OSB Partnerlink and we have to create an input and output variable here.


You only have to add some assign process activities to fill or retrieve the input and output variable.

FEEDJIT Live Traffic Map

My Blog List