Yesterday I had a mail-exchange with a colleague. He was giving an ADF-course, where students complained that in the market little was known about the techniques that they had to work with. Espessially that there's nobody who knows everything. The actual question was about security and SAML. This post is not about that, see my previous one. But I figured that although I did quite a lot with SOA/BPMSuite, OSB and other FMW tools, I do not know everything about Oracle the FMW SOA tools.
Today I took a look into the SplitJoin component of OSB. The last days I created a compound service in an OSB Proxy Service, where the different sub-components could be executed in parallel.
Having a closer look into the SplitJoin component it actually sort of amazed me.
Although you can do a sort of process modelling in a proxyservice, including if-then-else, loops, etc. you can't do parallism. The name of the SplitJoin already suggests that this is intended to solve just that. But the name of the component not nearly suggests what it actually is.
To create a split join, you'll have to create a new component:
Then OEPE asks for a binding/operation in a wsdl in your project. The resulting component has an extension that a little better suggests the specifics of the component: '.flow'.
For this post I created a more or less dummy SplitJoin, and added a scope element with a fault-handler:
An experienced SOASuite developer might recognize the structure. For me another hint was the Design Palette:
The SplitJoin is actually a BPEL-Process! So you're not only can do parallel flows, but in the pallete you can see that there are several flow-control constructs available for the process:
- For Each
- If
- Parallel
- Raise/Reraise Error
- Repeate Until
- Scope
- While
- Wait
I'm not going to give a BPEL-small-course here. If you google on 'OSB SplitJoin Examples' you'll get several examples of SplitJoin constructions.
I will make several remarks here.
Firstly, given the names and constructions, apparently the supported BPEL version is BPEL 2.0. Secondly, you would think that you could inter-exchange bpel processes from SOASuite-BPEL. However if you implement several Assign Operations, you'll see that the different operations on the messages/variables are done in BEA-extensions. The Log operation is also a BEA-extension to the BPEL-Assign construct.
Furthermore, I found that you can't introspect into the xml-structure of the messages in the expression builders of the assign operations. Like I'm used to in JDeveloper BPEL Designer, or even in the OEPE ProxyService 'MessageFlow'-modeller. This is very inconvenient, because you'll have to edit the xpath-expressions by hand. And I found by trial and error that you couldn't refer to the root-element of the element. If you log a variable, you'll see the root-element. But apparently you'll have to refer to the sub-elements relatively from the variable. like: '$ServiceReply.part1//ns1:subElement'.
Although you can model a complete BPEL process in the SplitJoin, I would be reluctant to use it excessively in OSB. For a complex BPEL process I would use Oracle SOASuite. Not only because the Jdeveloper BPEL Designer is more convenient, the support of the Runtime Engine in EnterpriseManager is much better. In OSB you can't introspect into a running/completed instance as you can in EM.
Lastly, you can't call a SplitJoin/BPEL-flow directly from your ProxyService. You'll need to generate a BusinessService on it. This is actually quite simple: just right click on the SplitJoin -> Oracle Service Bus -> Generate Business Service.
In my case I created a simple wsdl specially for the SplitJoin solution. This one is then called from my proxy-service only for the parallelism part. The request and response messages are based on a separate xsd with the different request and response elements combined. In the ProxyService I already created functionality to aggregate and transform the response-parts to a combined response.
If you open the source of the SplitJoin-BPEL-flow, you'll get:
<?xml version="1.0" encoding="UTF-8"?>
<bpel:process name="SplitJoin"
targetNamespace="http://www.example.com/flow/CBS/V1/SplitJoin"
xmlns:tns="http://www.example.com/flow/CBS/V1/SplitJoin"
xmlns:bpel="http://docs.oasis-open.org/wsbpel/2.0/process/executable"
xmlns:rescon="http://www.bea.com/alsb/flow/resources/config"
xmlns:bea="http://www.bea.com/bpel/ui/extensions"
xmlns:ext="http://www.bea.com/bpel/extensions"
xmlns:expr="http://www.bea.com/wli/sb/stages/config"
xmlns:trf="http://www.bea.com/wli/sb/stages/transform/config"
xmlns:bind="http://xmlns.darwin-it.nl/CDM/wsdl/V1/CBS/Service"
bea:name="SplitJoin">
<bpel:partnerLinks>
<bpel:partnerLink name="SplitJoin" partnerLinkType="tns:SplitJoin"
myRole="SplitJoin">
</bpel:partnerLink>
</bpel:partnerLinks>
<bpel:variables>
<bpel:variable name="request"
messageType="bind:requestMessage">
</bpel:variable>
<bpel:variable name="response"
messageType="bind:responseMessage">
</bpel:variable>
</bpel:variables>
<bpel:sequence>
<bpel:receive partnerLink="SplitJoin" operation="serviceOperation" variable="request" createInstance="yes">
<rescon:receiveInfo>
<rescon:wsdl ref="CDM/wsdl/V1/CBS/service" binding="bind:Service_pttSOAP11Binding"/>
</rescon:receiveInfo>
</bpel:receive>
<bpel:reply partnerLink="SplitJoin" operation="serviceOperation" variable="response"></bpel:reply>
</bpel:sequence>
</bpel:process>
The splitJoin is a nice component. But it's unclear to me why a seperate engine is added just to be able to do parallism. And the designer could be improved. But better still: leave it over to the SOASuite BPEL designer and engine. For me personally I'm not sure to what extend I should use this..