6 min read

The hello process service is a simplified example of a WS-BPEL process service. It doesn’t use partner services to get the job done, simply composing a hello message based on the data sent by the client. In contrast, a real-world WS-BPEL process may invoke a lot of partner services during its execution.

The following sections take you through creating the documents composing the bpr archive of a poInfo WS-BPEL process service that interacts with two partner services. The partner services used in this example are the following: poOrderDocService and poOrderStatusService.

The poInfo process service discussed here is invoked when a client sends a request message containing two parameters: pono and par. The first one specifies the pono of the order document on which you need to get information, while the second one specifies what kind of information should be returned, meaning two possible choices: the entire document or the status of the document.

Since you are going to deploy the poInfo process service to the ActiveBPEL engine, you first need to create the required folders in your file system for the project. For example, you may create the folder named poInfo and then create the META-INF, bpel, and wsdl folders within it.

Creating the WSDL Definition Describing the WS-BPEL Process

As usual, the first step in creating the service is to create the WSDL definition describing that service to its clients. Here is the poInfo.wsdl document that you should save in the wsdl folder created within the poInfo folder, which is the root folder for this project:

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="poInfo"
targetNamespace=
"http://localhost:8081/active-bpel/services/poInfoService.wsdl"




>
<import namespace="http://localhost/WebServices/wsdl/poOrderDoc"
location="http://localhost/WebServices/wsdl/po_orderdoc.wsdl"/>
<import namespace="http://localhost/WebServices/wsdl/poOrderStatus"
location="http://localhost/WebServices/wsdl/po_orderstatus.wsdl"/>
<types>
<schema attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace=
"http://localhost:8081/active-bpel/services/poInfoService.wsdl"
>
<element name="poInfoRequest">
<complexType>
<sequence>
<element name="pono" type="xsd:string"/>
<element name="par" type="xsd:string"/>
</sequence>
</complexType>
</element>
</schema>
</types>
<message name="poInfoResponseMessage">
<part name="payload" type="xsd:string"/>
</message>
<message name="poInfoRequestMessage">
<part name="payload" element="tns:poInfoRequest"/>
</message>
<portType name="poInfoPT">
<operation name="getInfo">
<input message="tns:poInfoRequestMessage"/>
<output message="tns:poInfoResponseMessage"/>
</operation>
</portType>
<plnk:partnerLinkType name="poInfoLT">
<plnk:role name="poInfoProviderRole">
<plnk:portType name="tns:poInfoPT"/>
</plnk:role>
</plnk:partnerLinkType>
<plnk:partnerLinkType name="poDocLT">
<plnk:role name="poDocProviderRole">
<plnk:portType name="ns2:poOrderDocServicePortType"/>
</plnk:role>
</plnk:partnerLinkType>
<plnk:partnerLinkType name="poStatusLT">
<plnk:role name="poStatusProviderRole">
<plnk:portType name="ns3:poOrderStatusServicePortType"/>
</plnk:role>
</plnk:partnerLinkType>
</definitions>

As you can see, the above WSDL definition imports two definitions describing the poOrderDocService and poOrderStatusService partner services.

Note the use of the poInfoRequest complex type when defining the input message. This structure makes it possible for the client to send two parameters, namely pono and par, within a single request message.

Another important thing to note here is the use of three partner links. The first one defines the interaction between the WS-BPEL process service and its client, while the other two define the relationships between the WS-BPEL service and the poOrderDocService and poOrderStatusService partner services respectively.

Creating the WSDL Catalog

The next step is to create the wsdlCatalog.xml WSDL catalog document in the META-INF directory of the project. In this example, the document contains only one entry that refers to the poInfo.wsdl document discussed in the preceding section.

<?xml version="1.0" encoding="UTF-8"?>
<wsdlCatalog>
<wsdlEntry location="wsdl/poInfo.wsdl"
classpath="wsdl/poInfo.wsdl" />
</wsdlCatalog>

Creating the WS-BPEL Business Definition Containing Conditional Logic

The WS-BPEL definition you create in this example is a bit complicated. This is because the poInfo.bpel definition shown below contains conditional logic.

<?xml version="1.0" encoding="UTF-8"?>
<process



name="poInfo.bpel"
suppressJoinFailure="yes"
targetNamespace="http://poInfo.bpel">
<import importType="http://schemas.xmlsoap.org/wsdl/"
location="wsdl/poInfo.wsdl"
namespace=
"http://localhost:8081/active-bpel/services/poInfoService.wsdl"/>
<import importType="http://schemas.xmlsoap.org/wsdl/"
location="http://localhost/WebServices/wsdl/po_orderdoc.wsdl"
namespace="http://localhost/WebServices/wsdl/poOrderDoc"/>
<import importType="http://schemas.xmlsoap.org/wsdl/"
location="http://localhost/WebServices/wsdl/po_orderstatus.wsdl"
namespace=
"http://localhost/WebServices/wsdl/poOrderStatus"/>

<partnerLinks>
<partnerLink myRole="poInfoProviderRole" name="poInfoProvider"
partnerLinkType="ns1:poInfoLT"/>
<partnerLink name="poDocRequester" partnerLinkType="ns1:poDocLT"
partnerRole="poDocProviderRole"/>
<partnerLink name="poStatusRequester" partnerLinkType="ns1:
poStatusLT" partnerRole="poStatusProviderRole"/>
</partnerLinks>
<variables>
<variable messageType="ns1:poInfoRequestMessage" name="poInfoReq
uestMessage"/>
<variable messageType="ns1:poInfoResponseMessage" name="poInfoRe
sponseMessage"/>
<variable messageType="ns2:getOrderDocInput" name="poDocRequest
Message"/>
<variable messageType="ns2:getOrderDocOutput" name="poDocRespon
seMessage"/>
<variable messageType="ns3:getOrderStatusInput" name="poStatusRe
questMessage"/>
<variable messageType="ns3:getOrderStatusOutput" name="poStatusR
esponseMessage"/>
</variables>
<sequence>
<receive createInstance="yes"
operation="getInfo"
partnerLink="poInfoProvider"
portType="ns1:poInfoPT"
variable="poInfoRequestMessage"/>
<if>
<condition>($poInfoRequestMessage.payload/ns1:par =
'doc')</condition>
<sequence>
<assign>
<copy>
<from part="payload" variable="poInfoRequestMessage">
<query>ns1:pono</query>
</from>
<to part="pono" variable="poDocRequestMessage"/>
</copy>
</assign>
<invoke inputVariable="poDocRequestMessage"
outputVariable="poDocResponseMessage"
operation="getOrderDoc"
partnerLink="poDocRequester"
portType="ns2:poOrderDocServicePortType">
</invoke>
<assign>
<copy>
<from>$poDocResponseMessage.doc</from>
<to>$poInfoResponseMessage.payload</to>
</copy>
</assign>
</sequence>
<elseif>
<condition>($poInfoRequestMessage.payload/ns1:par =
'status')</condition>
<sequence>
<assign>
<copy>
<from part="payload" variable="poInfoRequestMessage">
<query>ns1:pono</query>
</from>
<to part="pono" variable="poStatusRequestMessage"/>
</copy>
</assign>
<invoke inputVariable="poStatusRequestMessage"
outputVariable="poStatusResponseMessage"
operation="getOrderStatus"
partnerLink="poStatusRequester"
portType="ns3:poOrderStatusServicePortType">
</invoke>
<assign>
<copy>
<from>$poStatusResponseMessage.status</from>
<to>$poInfoResponseMessage.payload</to>
</copy>
</assign>
</sequence>
</elseif>
<else>
<assign>
<copy>
<from>'Wrong input parameter. Should be either
doc or status!'</from>
<to>$poInfoResponseMessage.payload</to>
</copy>
</assign>
</else>
</if>
<reply operation="getInfo"
partnerLink="poInfoProvider"
portType="ns1:poInfoPT"
variable="poInfoResponseMessage"/>
</sequence>
</process>

The most interesting part of the above WS-BPEL process definition is the if/ elseif/else construct. Schematically it looks like the following:

<sequence>

activities

<if>
<condition>...</condition>
<sequence>

activities

</sequence>
<elseif>
<condition>...</condition>

<sequence>

activities

</sequence>
</elseif>
<else>
activity
</else>
</if>

activities

</sequence>

Note the use of the inner sequence constructs in the above structure. The fact is that WS-BPEL doesn’t allow you to use more than one activity within if or elseif or else blocks. That is why you have to enclose a set of activities within any of those blocks with sequence.

LEAVE A REPLY

Please enter your comment!
Please enter your name here