Thursday, January 17, 2008

Calling (basic) secured Webservices

If a webservice is secured by basic authentication you can call this web service by supplying the basic credentials. This is done at the partner link definition. For BPEL these are the properties in JDeveloper of the partner link. Or you could add them directly in the bpel.xml file in the partner link binding.

<partnerlinkbinding name="YourPartnerLink">
<property name="wsdlLocation">YourPartnerLink.wsdl</property>
<property name="basicHeaders">credentials</property>
<property name="basicUsername">myusername</property>
<property name="basicPassword">thisissecret</property>
</partnerlinkbinding>

Or using the http username password mechanism:

<partnerlinkbinding name="YourPartnerLink">
<property name="wsdlLocation">YourPartnerLink.wsdl</property>
<property name="httpHeaders">credentials</property>
<property name="httpUsername">myusername</property>
<property name="httpPassword">thisissecret</property>
</partnerlinkbinding>

Wednesday, January 16, 2008

Removing a node from node-list

With the bpelx: extensions in BPEL you are able to insert and update nodes in a node list. A node-list is an XML message that contains a set of records. In this article I use the following example:
<BookList xmlns="http://message.vijfhuizen.com">
<Book>
<title>The Lord Of The Rings</title>
<author>J.R.R. Tolkien</author>
</Book>
<Book>
<title>Harry Potter</title>
<author>J.R.R. Tolkien</author>
</Book>
<Book>
<title>The Hobbit</title>
<author>J.R.R. Tolkien</author>
</Book>
<Book>
<title>Storm; Chronicals of Pandarve</title>
<author>Don Lawrence</author>
</Book>
</BookList>

For creating and updating node lists the bpelx: functions are enough to handle this. But when you want to remove a particular node, you can use the bpelx:remove function. But this function can only remove a node from a particular position. For example removing the second node you code:
<bpel:assign>
<bpelx:remove>
<bpelx:target variable="VarBookList" query="/Booklist/Book[2]" />
</bpelx:append>
</bpel:assign>

It is hard to code the bpelx:remove to create a xpath to dynamicly remove node. You would like to remove the second node based on the xpath:
/Booklist/Book[title="Harry Potter" and author="J.R.R. Tolkien"]
You can add the above xpath in the bpelx:remove, but you are not able to make this dynamically.

There is a solution. The trick is to create a stylesheet that copies the data into a new message, but removing that particular records. Create a stylesheet that does the normal copy of the XML message. Then add a <choose> element in the stylsheet to filter that particular record.
  <xsl:template match="/">
<BookList>
<xsl:for-each select="/BookList/Book">
<xsl:choose>
<xsl:when test="title='Harry Potter' and author='J.R.R. Tolkien'"/>
<xsl:otherwise>
<Book>
<title>
<xsl:value-of select="title"/>
</title>
<author>
<xsl:value-of select="author"/>
</author>
</Book>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</BookList>

Now we have a XSL stylesheet that removes a particular record, but this is not variable. This can be done via XSLT parameters.
  <xsl:param name="pTitle"/>
<xsl:param name="pAuthor"/>
<xsl:template match="/">
<BookList>
<xsl:for-each select="/BookList/Book">
<xsl:choose>
<xsl:when test="title=$pTitle and author=$pAuthor"/>
<xsl:otherwise>
<Book>
<title>
<xsl:value-of select="title"/>
</title>
<author>
<xsl:value-of select="author"/>
</author>
</Book>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</BookList>
</xsl:template>
Now we are able to use this stylesheet in BPEL. In general BPEL create the following code:
  <assign name="Transform">
<bpelx:annotation>
<bpelx:pattern>transformation</bpelx:pattern>
</bpelx:annotation>
<copy>
<from expression="ora:processXSLT('RemoveNode.xsl'
, bpws:getVariableData('Variable_BookList','payload')" />
<to variable="Variable_BookListTemp" part="payload"/>
</copy>
</assign>
But this code does not pass parameters to the stylesheet. The ora:processXSLT() can do this it has an additional parameter in this function:
  <assign name="Transform">
<bpelx:annotation>
<bpelx:pattern>transformation</bpelx:pattern>
</bpelx:annotation>
<copy>
<from expression="ora:processXSLT('RemoveNode.xsl'
, bpws:getVariableData('Variable_BookList','payload')" />
, bpws:getVariableData('BPELxslparameters'))"/>
<to variable="Variable_BookListTemp" part="payload"/>
</copy>
</assign>
Now only you have to create the BPELxslparameters variable and assign it with the correct name/value pairs. The structure of the this variable is as follows:
  <?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.oracle.com/service/bpel/common"
targetNamespace="http://schemas.oracle.com/service/bpel/common"
elementFormDefault="qualified">
<xsd:element name="parameters">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="item" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="value" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Create in BPEL the variable BPELxslparameters and let it point to this strucure:
    <process ....
xmlns:common="http://schemas.oracle.com/service/bpel/common"
.../>
<variable name="BPELparameters" element="common:parameters"/>
Now we can in BPEL create an empty XML message, based on this strcuture and assign the values to these parameters and then call the processXSLT function.
  <bpelx:assign name="Assign_GenerateEmptyParameterSet">
<copy>
<from>
<parameters xmlns="http://schemas.oracle.com/service/bpel/common">
<item>
<name>pTitle</name>
<value/>
</item>
<item>
<name>pAutor</name>
<value/>
</item>
</parameters>
</from>
<to variable="BPELparameters" query="/common:parameters"/>
</copy>
</bpelx:assign>
<assign name="Assign_setXSLTParameters">
<copy>
<from expression="'Harry Potter'"/>
<to variable="BPELparameters" query="/common:parameters/common:item[1]/common:value"/>
</copy>
<copy>
<from expression="'J.R.R. Tolkien'"/>
<to variable="BPELparameters" query="/common:parameters/common:item[1]/common:value"/>
</copy>
</assign>

BPEL handling semaphores

General
Semaphores are normally used in low level operating systems to control processes. The mechanism is used to hold-up process. A particular process will not go further if it can not obtain a semaphore. Multiple processes can wait for a single semaphore.

A detailed description of semaphores is written in Wikipedia or in a book that I used decades ago .

Creating BPEL orchestration processes, you basically need semaphores to make sure that a single process can execute a particular task before any other process will do the same. For example; before a message is send by a process to must undergo an initialization or sending a new message. If more then one processes are running, only one process may send this message.

BPEL
In BPEL a semaphore mechanism is implemented. A semaphore handler process is implemented that is running as a singleton.

This process will process messages in a sequence. It keeps track of all the semaphores that will be Acquired or Released. A second process is communicates with this process and the outside world. It can take two operations;
  • Acquire - get a semaphore or wait.
  • Release - release a acquired semaphore.

The name of the two processes are that are created are:
  • Semaphore
  • SemaphoreHandler
The Semaphore process is implemented as a synchronous process. This is explicitly done, because semaphores are meant to be short living. On O/S level, they exist in microseconds. In BPEL I expect this to be milliseconds.

The logical flow of an semaphore is shown as follows.


An BPEL Process will Acquire a semaphore. If this semaphore is available, it 'gets' the semaphore. This means that the BPEL process 'SemaphoreHandler' is keeping track of this. If a second BPEL process wants to acquire the same semaphore, it will not get this semaphore. This process will wait. If the first BPEL process releases the semaphore, the 'SemaphoreHandler' process replies with a 'Release' and the second process gets an 'Acquired'.

An example can be downloaded here.

Steps to implement:

  • Unzip the file in your local directory
  • Start JDeveloper 10.1.3.3
  • Open the workspace.
  • Compile and deploy the to your SOA Suite server:
  • Semaphore
  • SemaphoreHandler
  • SemaphoreTest
To run the application, you must first start the SemaphoreHandler process. Start this process via the '' operation with as payload:
<?xml version = '1.0' encoding = 'UTF-8'?>
<SemaphoreHandlerInitiateRequest xmlns="http://xmlns.oracle.com/SemaphoreHandler">
<SemaphoreHandlerId>SemaphoreHandler/1.0</SemaphoreHandlerId>
</SemaphoreHandlerInitiateRequest>

Initiate the SemaphoreTest process to test Semaphore mechanism.

The Semaphore process can be used via two operations; Acquire and Release. With both operations the name of the Semaphore must be supplied. You must use both operations within the scope of the calling process. The Semaphore detects automatically the process id of his parent process. This process id is used for correlation between "Semaphore" and the "SemaphoreHandler" process. If the "Semaphore" process is called directly, for example via the BPEL console or via SoapUI, there is no parent process. In this case the local process id is used as correlation.

Furthermore, if an semaphore can not be obtained within a specific period, a timeout will occur.

The internal message structure of the "SemaphoreHandler" for holding the semaphores is as follows:

<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://xmlns.oracle.com/listOfSemaphores"
targetNamespace="http://xmlns.oracle.com/listOfSemaphores"
elementFormDefault="qualified">
<xsd:element name="listOf-Semaphores" type="listOf-SemaphoresTypes"/>
<xsd:complexType name="listOf-SemaphoresTypes">
<xsd:sequence minOccurs="1" maxOccurs="unbounded">
<xsd:element name="Semaphore" type="SemaphoresTypes" minOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="SemaphoresTypes">
<xsd:sequence>
<xsd:element name="Name" type="xsd:string" minOccurs="1"/>
<xsd:element name="ProcessId" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

In the "SemaphoreHandler" process this XML message is build up. The "Name" is the name of the semaphore while the "ProcessId" is the process id of the calling process "Semaphore". If an semaphore already exist in the list, you can not acquire the semaphore. The acquisition is added to the list. If a release of a semaphore is asked, it can only be done if it exists in the list in combination with the process-Id.

Notes
This solution is working for a non-clustered environment. The current solution is based on a in-memory structure of the semaphores. For a clustered environment, this memory structure must be shared. A solution for this is to hold this structure in Oracle Coherence. This is a shared stored area to keep data in sync over multiple application servers.

The storage is now done in-memory, you could change this to store this somewhere else; like a database table or file or even with Oracle Coherence. This will make the solution more reliable.