Thursday, July 10, 2014

Split-join is a feature in Oracle Service Bus which allows to process messages in parallel. Split-Join is useful to reduce overall processing time as we process messages in parallel. As name suggest Split-Join split the request message to individual message and invoke business services in parallel, get the response from each business service and join that response.

There are two types if Split-Joins in Oracle Service Bus.
  • Static Split-Join
  • Dynamic Split-Join

In this post, we will discuss about Static Split-Join. In Static Split-Join, we have fixed number of parallel branches that we need to determine at design level only.

I will show one use case of Split-Join in this post which is based on below scenario.

Customer Portal need customer information from back end system to display it on the portal but all required information is not present in one system; it is present in two different systems. Customer Name information is stored in first system and Customer address information is stored in second system. So we need to get this information, join the information and send it to customer portal.

We use static split-join to design above scenario; in static split-join we add two branches which execute in parallel, one to get Customer name and other to get customer address.

Let’s start with this use case. We use eclipse to build static join as we can’t built it from OSB console.

First create an OSB project and add required folder structure to it.

Import below artifacts to OSB project.
  • Customer Name service WSDL and XSD file: We use this to create business service which will be called from split join to get customer name.
  • Customer Address service WSDL and XSD file: we use this to create business service which will be called from split-join to get customer address information.
  • Customer Info Service WSDL and XSD file: we use this to create split join, this service define the request and response structure of message required by customer portal.


 Now we create business services for customer name and customer address services.





Repeat above step for Customer Address Business service.

Now we create split-join, right click on split join folder à New à Split-Join

Choose Customer Info service operation.



 Now add “Parallel” Flow control activity to after receive activity in split-join.

Since we need to invoke only two services from this split-join so we need only two branches in parallel flow, now add invoke activity in each branch. Invoke activity used to call business service.

Configure invoke activity to invoke Customer Name business service.





Repeat above steps for Customer Address Services.

Once you configure the invoke activity to call business services then we need to create request and response variables for both customer name and address services.

Create these variables as local.



Once you complete the above step, your split join flow looks like below.



Now we need to initialize request variable, if you don’t initialize these variable then at run time you will get error.

To initialize and assign value to request message, add assign activity above invoke activity.  From variable drop down select customer name service request message then click on “Expression”.

Add below text in the expression, this will initialize the request message and assign required input value to it.

<ns1:process>
<ns1:CustomerId>{$request.payload/bind:CustomerId/text()}</ns1:CustomerId>
</ns1:process>




Repeat above step for customer address request message variable assignment. Add below text for customer address request message in expression box.

<ns0:process>
<ns0:CustomerId>{$request.payload/bind:CustomerId/text()}</ns0:CustomerId>
</ns0:process>


After service invocation, we get the response from each service. Now we need to join the response from both the services to one final response.

Since we have created local variable for customer name and address services so we will not be access these variables outside parallel flow control. So to get the response of both the services, we create two global variables based on service response message.  

After each invocation, we assign response from service to these global variables and then use these variables to join the response to final response.

To create global variable, go to top of the split-join, right click on variables and choose “Create variable”.

Create two global variables, one for each service response.



Now as mentioned above, we assign service response to above created global variables.

To do that, add assign activity after invoke activity, choose variable from variable drop down and click on expression.

Add below test to initialize the global variable and assign service response to it.

Customer Name Service

<ns1:processResponse>
<ns1:CustomerFirstName>{$getCustomerNameRespMsg.payload/ns1:CustomerFirstName/text()}</ns1:CustomerFirstName>
<ns1:CustomerLastName>{$getCustomerNameRespMsg.payload/ns1:CustomerLastName/text()}</ns1:CustomerLastName>
</ns1:processResponse>

Customer Address Service

<ns0:processResponse>
<ns0:CustomerCity>{$getCustomerAddressRespMsg.payload/ns0:CustomerCity/text()}</ns0:CustomerCity>
<ns0:CustomerCountry>{$getCustomerAddressRespMsg.payload/ns0:CustomerCountry/text()}</ns0:CustomerCountry>
</ns0:processResponse>



Now we need to assign each service response to final response. Since we can’t access service response variables outside parallel flow control so we use global variables to assign final response.

To do that add assign activity before reply activity, choose response variable from variable drop down and click on expression.

Add below text in expression box.

<bind:processResponse>
<bind:CustomerFirstName>{$customerNameInfo.payload/ns1:CustomerFirstName/text()}</bind:CustomerFirstName>
<bind:CustomerLastName>{$customerNameInfo.payload/ns1:CustomerLastName/text()}</bind:CustomerLastName>
<bind:CustomerCity>{$customerAddressInfo.payload/ns0:CustomerCity/text()}</bind:CustomerCity>
<bind:CustomerCountry>{$customerAddressInfo.payload/ns0:CustomerCountry/text()}</bind:CustomerCountry>
</bind:processResponse>



Your final split join should look like below.




We can’t use split join as it in proxy message flow, we need to generate business service from split-join and then we can use it.

To do that right click on split join and go to “Oracle Service Bus” and then click on “Generate Business Service”. This will generate business service for your split join.



Now deploy your project to OSB server and test the business service which we created from split-join.





Download sample code from here.







14 comments :

  1. This comment has been removed by the author.

    ReplyDelete
  2. Dear Vivek,

    Please share the .jar file for this wonderful service.

    thank you
    pratiksharma172000@gmail.com

    ReplyDelete
    Replies
    1. Hi Pratik,

      I have added the jar file to the post. You can download it from the post link.

      Thanks
      Vivek Garg

      Delete
    2. Hi Vivek can we have stuff for how to do manual deployment of Oracle bam 12c in terms of import and export

      Delete
  3. Hi ,

    Very nice article .Could you please share .jar file or wsdl's and xsd's for this split join service

    Thanks in Advance
    challanirmal@gmail.com

    ReplyDelete
    Replies
    1. Hi Nirmal,

      I have added the jar file to the post.

      Thanks
      Vivek Garg

      Delete
  4. Hi Vivek,

    Thank you very much for your fast response and providing jar file for us

    I have question

    How to configure An appropriate timeout on OSB business service based on target system ?

    ReplyDelete
    Replies
    1. Hi Nirmal,

      You can check below post (SLA Alerts).

      http://soawork.blogspot.com/2014/06/sla-alerts-in-osb.html

      Thanks
      Vivek Garg

      Delete
  5. Hi,
    I cant test service.

    Also, when I am trying to import the WSDL in SoapUI to use it as a Mock Service, its showing me some definition error.

    "WSDLException (at /con:wsdlEntry): faultCode=INVALID_WSDL: Expected element '{http://schemas.xmlsoap.org/wsdl/}definitions'."

    Could you please guide?

    thanks well in advance

    ReplyDelete
    Replies
    1. HI Pratik,

      How you imported the WSDL of proxy service to SOAP UI ? I suggest you to export the proxy wsdl from osb console and import it to SOAP UI or you can use the proxy endpoint in SOAP UI.

      Thanks
      Vivek

      Delete
  6. Hi

    Getting this error when running the split-join in EM.


    The invocation resulted in an error: [{http://schemas.xmlsoap.org/soap/envelope/}Server] [OSB-380002] Not Found.





    soap-env:Server
    [OSB-380002] Not Found






    ReplyDelete
    Replies
    1. Please paste full error trace here to analyze the error.

      Delete
  7. Vivek,

    Can you please guide me how to do error handler for this?. Say One DB is down and flow needs to continue.

    Vignesh

    ReplyDelete
  8. Note that there is a convenient wrapper over Split-Join - the GenericParallel library - which not only makes things way easier, but also fixes some known shortcomings of Split-Join. It is free and open-source.

    ReplyDelete