SOA: Implementing Service-Oriented Orchestrations

Exclusive offer: get 100% off this eBook here
SOA and WS-BPEL

SOA and WS-BPEL — Save 100%

Compose Service-Oriented Architecture Solutions with PHP and Open-Source ActiveBPEL with this book and eBook

$29.99    $0.00
by Yuli Vasiliev | May 2010 | .NET BPEL Microsoft SOA Web Services

This article by Yuli Vasiliev, author of the book SOA and WS-BPEL, dicusses how to implement service-oriented orchestrations using WS-BPEL.

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"
xmlns:tns=
"http://localhost:8081/active-bpel/services/poInfoService.wsdl"
xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns2="http://localhost/WebServices/wsdl/poOrderDoc"
xmlns:ns3="http://localhost/WebServices/wsdl/poOrderStatus"
xmlns="http://schemas.xmlsoap.org/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"
xmlns="http://www.w3.org/2001/XMLSchema">
<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 xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/
executable"
xmlns:ns1=
"http://localhost:8081/active-bpel/services/poInfoService.wsdl"
xmlns:ns2="http://localhost/WebServices/wsdl/poOrderDoc"
xmlns:ns3="http://localhost/WebServices/wsdl/poOrderStatus"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
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.

SOA and WS-BPEL Compose Service-Oriented Architecture Solutions with PHP and Open-Source ActiveBPEL with this book and eBook
Published: September 2007
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

Creating the PDD Document

Before you build the deployment archive for this project, you need to create the Process Deployment Descriptor document. Here is the poInfo.pdd document that you should save in the root folder of the project:

<?xml version="1.0" encoding="UTF-8"?>
<process xmlns="http://schemas.active-endpoints.com/pdd/2006/08/pdd.
xsd"
xmlns:bpelns="http://poInfo.bpel"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing"
location="bpel/poInfo.bpel"
name="bpelns:poInfo.bpel">
<partnerLinks>
<partnerLink name="poDocRequester">
<partnerRole endpointReference="static">
<wsa:EndpointReference xmlns:s=
"http://localhost/WebServices/wsdl/poOrderDoc">
<wsa:Address>http://localhost/WebServices/ch4/
SoapServer_orderdoc.php
</wsa:Address>
<wsa:ServiceName PortName=
"poOrderDocServicePort">s:poOrderDocService</wsa:ServiceName>
</wsa:EndpointReference>
</partnerRole>
</partnerLink>
<partnerLink name="poStatusRequester">
<partnerRole endpointReference="static">
<wsa:EndpointReference xmlns:s=
"http://localhost/WebServices/wsdl/poOrderStatus">
<wsa:Address>http://localhost/WebServices/ch4/
SoapServer_orderstatus. php</wsa:Address>
<wsa:ServiceName PortName="poOrderStatusServicePort">
s:poOrderStatusService</wsa:ServiceName>
</wsa:EndpointReference>
</partnerRole>
</partnerLink>
<partnerLink name="poInfoProvider">
<myRole allowedRoles="" binding="RPC"
service="poInfoService"/>
</partnerLink>
</partnerLinks>
<wsdlReferences>
<wsdl location=
"http://localhost/WebServices/wsdl/po_orderdoc.wsdl"
namespace="http://localhost/WebServices/wsdl/poOrderDoc"/>
<wsdl location=
"http://localhost/WebServices/wsdl/po_orderstatus.wsdl"
namespace="http://localhost/WebServices/wsdl/poOrderStatus"/>
<wsdl location="wsdl/poInfo.wsdl" namespace=
"http://localhost:8081/active-bpel/services/poInfoService.wsdl"/>
</wsdlReferences>
</process>

As you can see, the above pdd document contains three partnerLink sections, each of which is related to the corresponding partnerLink section defined in the process definition discussed in the preceding section.

Deploying the WS-BPEL Process Service

Now that you have all the project components ready, you can create the deployment archive.

Using your operating-system command prompt, you should change the current directory to the root directory of the project, and then issue the following command:

jar cf poInfo.bpr *.pdd META-INF bpel wsdl

As a result, you should have a deployable poInfo.bpr archive. Make sure to copy that file to the $CATALINA_HOME/bpr directory to deploy it to the ActiveBPEL engine.

To make sure that the process has been successfully deployed, you can use the BPEL Administrative Console, loading the Deployment Log page. Or you can enter the following URL in your browser:

http://localhost:8081/active-bpel/services/poInfoService?wsdl

As a result, you should see the WSDL based on the poInfo.wsdl with the service and binding sections automatically added by the ActiveBPEL engine.

Testing the WS-BPEL Process Service

After the poInfo process service has been successfully deployed, it's time to test it. For that, you might create and then run the following PHP script:

<?php
//File: SoapClient_poInfo.php
$client = new SoapClient
("http://localhost:8081/active-bpel/services/poInfoService?wsdl");
$xmldoc = '<wrapper><pono>108128476</pono><par>doc</par></wrapper>';
$xmldoc = simplexml_load_string($xmldoc);
try {
print($client->getInfo($xmldoc));
}
catch (SoapFault $e) {
print $e->getMessage();
}
?>

This should output the entire po document whose pono is 108128476. When setting the $xmldoc variable in the above script as shown below:

$xmldoc = '<wrapper><pono>108128476</pono><par>status</par></
wrapper>';

you should receive a short message: shipped, which indicates the status of the document.

Summary

In this article, we have learnt how WS-BPEL can be used to build WS-BPEL orchestrations that combine single loosely coupled services into composite stateful applications.

If you have read this article you may be interested to view :

SOA and WS-BPEL Compose Service-Oriented Architecture Solutions with PHP and Open-Source ActiveBPEL with this book and eBook
Published: September 2007
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

About the Author :


Yuli Vasiliev

Yuli Vasiliev is a software developer, freelance author, and consultant currently specializing in open-source development, Oracle technologies, and service-oriented architecture (SOA). He has over 10 years of software development experience as well as several years of technical writing experience. He wrote a series of technical articles for Oracle Technology Network (OTN) and Oracle Magazine.

Contact Yuli Vasiliev

Books From Packt

Business Process Driven SOA using BPMN and BPEL
Business Process Driven SOA using BPMN and BPEL

Business Process Execution Language for Web Services 2nd Edition
Business Process Execution Language for Web Services 2nd Edition

Service Oriented Java Business Integration
Service Oriented Java Business Integration

SOA Approach to Integration
SOA Approach to Integration

RESTful Java Web Services
RESTful Java Web Services

Oracle Web Services Manager
Oracle Web Services Manager

.NET Compact Framework 3.5 Data Driven Applications
.NET Compact Framework 3.5 Data Driven Applications

Microsoft Silverlight 4 Data and Services Cookbook
Microsoft Silverlight 4 Data and Services Cookbook

No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
b
5
j
t
9
z
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software