Friday, August 31, 2007

Dynamic Endpoints in Cape Clear BPEL

Creating dynamic endpoints in BPEL using Cape Clear is pretty easy. Just simply overwrite the PartnerLink using an Assign/Copy activity where the From value is the URL and the To is the partnerlink. Having done this in a previous implementation I statically defined these URLs in the BPEL itself. I could have developed a WS that returned the dynamic endpoint but thought that was too much for what was needed at the time. The URLs were static and would not change. Well 6 months later, the URLs are changing as new destinations are being added to the BPEL, in fact double the destinations.

I am now refactoring the current BPEL to use a new feature in Cape Clear BPEL, the XPath function getInitValueParam(). The getInitValueParam() function allows me to send in a property name as a string and get back its value. These properties are defined in the initParams section of the Cape Clear deployment descriptor (ws-application.xml).

I am also employing a while loop to examine the inbound XML for destination data and in combination with the above function, parameterize the destinations externally to the BPEL.

Here is the scenario, an inbound XML messages defines the names of the various intermediaries in the overall process. This is represented in an element called system as shown below:

<system>systema<system>
<system>systemb<system>

The system element is unbounded but is an enumeration of valid destinations. Within the new BPEL, a counter is initialized and a while loop determines if the counter is less than or equal to the number of recipients. For each system I wanted to extract the system element value (the SOAP intermediary name) and then use the getInitValueParam() function to return the destinations URL . I then overwrite the PartnerLink value with this destination and I have performed dynamic endpoint assignment.

Sounds good right! Well I finally got it working through the help of a fellow BPEL blogger. The problem that I had was accessing the system element via array notation. My array value was defined as a variable called counter. I tried using a combination of XPath that would get me down to the system node and then combine this with bpws:getVariableData() of the counter value. No luck. I found this link which got me through the issue quickly:

http://covarm.tvu.ac.uk/blog/?p=4

Basically, it was necessary to use the concat function in a Copy activity to create a xpath query that builds the actual expression I was interested in, in this case something like:

concat('.../.../ns1:system[', bpws:getVariableData('counter'),']' )

then, this value was assigned to a variable called xpath. Then in the next Copy activity I refer to the new variable xpath:

bpws:getVariableData('...', 'parameters', bpws:getVariableData('xpath') )

A lot of work to do something so simple in Java. Oh well, the combination of these features is helping dramatically simplify my original BPEL and providing unlimited scalability for new systems via configuration instead of coding.

No comments: