Take control with WS-BPEL

Page: 1 2 3 4 5 6 7 December 11th, 2009 by Henri Bezemer

In the sequence diagram below I’ve mapped a number of WSDL documents to message exchanges between partners. Each WSDL document depicted in the diagram contains the definitions for those message exchanges.BPEL example with WSDL

a WS-BPEL process requires additional elements to be included in WSDL documents, the so called partner link types. I already introduced the term partner. A partner link is a (not surprisingly) a link to a partner. A partner link type is a statement about the WSDL port type (the set of operations) that the partner provides or expects. The word “or” in the last phrase needs additional explanation: a partner link can be two-sided: the WS-BPEL process wants to talk to the partner and the partner might want to talk to the process (remember the term callback?). In WS-BPEL, each side of a partner link ”plays” a role (dubbed myRole and partnerRole from the perspective of the WS-BPEL process). The roles must be named appropriately. I suggest that you always draw up an interaction diagram (like the one presented in this post) and then use the names that you placed above the lifelines (the instance/object names) as role names.

I don’t think that it is a good idea to hack these WS-BPEL specific elements right into existing WSDL’s. It is cleaner to create new “wrapper” WSDLs that imports the original WSDLs and then add the extra’s – leaving the originals exactly that: originals. This rule especially applies in the case where the original WSDLs are not maintained by yourself. In the diagram there is the wrapper WSDL drawn for the bidirectional partner link type between the front-office BPEL process and the crm system. Here is this wrapper:

front-office-crm.wsdl

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

<definitions
    name="front-office-crm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.zienit.com/front-office-crm/wsdl"
    xmlns:tns="http://www.zienit.com/front-office-crm/wsdl"
    xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype"
    xmlns:crm="http://simpleejb.zienit.com"
    xmlns:focb="http://www.zienit.com/front-office-callback/wsdl"
    xmlns:fo-type="http://www.zienit.com/front-office/schema"
    xmlns:vprop="http://docs.oasis-open.org/wsbpel/2.0/varprop">
	<import location="localhost_8080/CRMService/CRMPortType.wsdl" namespace="http://simpleejb.zienit.com"/>
	<import location="front-office-callback.wsdl" namespace="http://www.zienit.com/front-office-callback/wsdl"/>
	<types>
		<xsd:schema targetNamespace="http://www.zienit.com/front-office-callback/wsdl">
			<xsd:import namespace="http://www.zienit.com/front-office/schema" schemaLocation="front-office.xsd"/>
			<xsd:import namespace="http://simpleejb.zienit.com" schemaLocation="http://192.168.1.51:8080/CRMService/CRMPortType?xsd=1"/>
		</xsd:schema>
	</types>
	<plnk:partnerLinkType name="FOCRMServiceLT">
		<plnk:role name="FrontOffice" portType="focb:FrontOfficeCBPT"/>
		<plnk:role name="CRM" portType="crm:CRMPortType"/>
	</plnk:partnerLinkType>
	<vprop:property name="email" type="xsd:string"/>
	<vprop:propertyAlias propertyName="tns:email" messageType="focb:notifyEmailConfirmedRequest" part="part1">
		<vprop:query>/fo-type:notifyEmailConfirmed/fo-type:email</vprop:query>
	</vprop:propertyAlias>
	<vprop:propertyAlias propertyName="tns:email" messageType="crm:addEmailResponse" part="parameters">
		<vprop:query>/crm:addEmailResponse/email/address</vprop:query>
	</vprop:propertyAlias>
</definitions>

This WSDL imports two other “regular” WSDL’s: CRMPortType.wsdl which describes the web service provided by the CRM system and front-office-callback.wsdl which describes the single call back operation provided by the WS-BPEL process itself. The partner link type is defined on lines 23 – 26, for two roles, “FrontOffice” and “CRM”.

The elements with the vprop: prefix deal with WS-BPEL correlation. Correlation is actually not a difficult concept to grasp. Correlation introduces properties. On line 27 I define a property of type string called email. Property values are attached to process instances and are scraped out of the messages that are going in and out of the WS-BPEL engine (I use the term scraping in the same sense as it is used in screen scraping). Properties are intended to make process instances uniquely identifiable. Take a look at the picture below. It shows three concurrently executing instances of a WS-BPEL process. One of the instances sends a message to a partner (depicted by a sequence diagram “lifeline”). A value (depicted by a key) is scraped from the message and stored in a property associated with the process instance (1) before the message is delivered to the partner (2). After a while the partner send a message back to the process. When the message arrives at the WS-BPEL engine, again a value is scraped from the message (3) and by comparing this value to the properties associated with the process instances, the right instance is found (4). The WS-BPEL engine can now deliver the message to this instance. The scraping of values from specific messages is done using XPath expressions (specified at lines 28 – 30 and 31 – 33). Later in this post, when we look at the WS-BPEL process itself we’ll see how these two different uses of properties (assign vs. lookup) are specified.

Off course, this all sounds nice and works well if only you can find some piece of identifying data in your messages. If it isn’t there, the only solution that you have is to somehow add this data to your messages. However, I believe that it is intrinsic to the nature of (web) services that something identifying is included in most messages.

correlationI’ll skip the WSDL for the CRM system. Again, refer to this post for more details. Here is the WSDL for the interface from the customer to the front-office process:

front-office.wsdl:

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="FrontOfficeService"
    targetNamespace="http://www.zienit.com/front-office/wsdl"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://www.zienit.com/front-office/wsdl"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:type="http://www.zienit.com/front-office/schema">
	<types>
		<xsd:schema  targetNamespace="http://www.zienit.com/front-office/wsdl">
			<xsd:import namespace="http://www.zienit.com/front-office/schema" schemaLocation="front-office.xsd"/>
		</xsd:schema>
	</types>
	<message name="createCustomerRequest">
		<part name="part1" element="type:createCustomer"/>
	</message>
	<message name="createCustomerResponse">
		<part name="part1" element="type:createCustomerResponse"/>
	</message>
	<portType name="FrontOfficePT">
		<operation name="createCustomer">
			<input name="input1" message="tns:createCustomerRequest"/>
			<output name="output1" message="tns:createCustomerResponse"/>
		</operation>
	</portType>
	<binding name="FrontOfficePTBinding" type="tns:FrontOfficePT">
		<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
		<operation name="createCustomer">
			<soap:operation/>
			<input name="input1">
				<soap:body use="literal"/>
			</input>
			<output name="output1">
				<soap:body use="literal"/>
			</output>
		</operation>
	</binding>
	<service name="FrontOfficeService">
		<port name="FrontOfficePort" binding="tns:FrontOfficePTBinding">
			<soap:address location="http://localhost:${HttpDefaultPort}/front-office/FrontOfficePT"/>
		</port>
	</service>
	<plnk:partnerLinkType name="FrontOfficeServiceLT">
		<plnk:role name="FrontOffice" portType="tns:FrontOfficePT"/>
	</plnk:partnerLinkType>
</definitions>

 This WSDL defines a service with a single synchronous operation. Note that this WSDL contains both the abstract and the concrete side of a web service. As already explained, for WS-BPEL an abstract definition of a web service is sufficient, it doesn’t care about the concrete protocol binding. However, the NetBeans CASA editor will inspect the concrete parts of the provided WSDL’s and will create a deployment unit that has the necessary binding components (BC’s) configured properly, for instance the HTTP BC and the File BC.

Here is the WSDL for the interface from the CRM system to the front-office process (the callback):

front-office-callback:

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="FrontOfficeCBService"
    targetNamespace="http://www.zienit.com/front-office-callback/wsdl"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://www.zienit.com/front-office-callback/wsdl"
    xmlns:type="http://www.zienit.com/front-office/schema"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
	<types>
		<xsd:schema  targetNamespace="http://www.zienit.com/front-office/wsdl">
			<xsd:import namespace="http://www.zienit.com/front-office/schema" schemaLocation="front-office.xsd"/>
		</xsd:schema>
	</types>
	<message name="notifyEmailConfirmedRequest">
		<part name="part1" element="type:notifyEmailConfirmed"/>
	</message>
	<portType name="FrontOfficeCBPT">
		<operation name="notifyEmailConfirmed">
			<input name="input1" message="tns:notifyEmailConfirmedRequest"/>
		</operation>
	</portType>
	<binding name="FrontOfficeCBBinding" type="tns:FrontOfficeCBPT">
		<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
		<operation name="notifyEmailConfirmed">
			<soap:operation/>
			<input name="input1">
				<soap:body use="literal"/>
			</input>
		</operation>
	</binding>
	<service name="FrontOfficeCBService">
		<port name="FrontOfficeCBPort" binding="tns:FrontOfficeCBBinding">
			<soap:address location="http://localhost:${HttpDefaultPort}/front-office/FrontOfficeCBPort"/>
		</port>
	</service>

</definitions>

Finally, here is the WSDL for the interface from front-office to back-office:

back-office-wsdl


<definitions name="back-office" targetNamespace="http://j2ee.netbeans.org/wsdl/Front-office/back-office"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:file="http://schemas.sun.com/jbi/wsdl-extensions/file/" xmlns:tns="http://j2ee.netbeans.org/wsdl/Front-office/back-office" xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype" xmlns:ns0="http://xml.netbeans.org/schema/back-office">
	<types>
		<xsd:schema targetNamespace="http://j2ee.netbeans.org/wsdl/Front-office/back-office">
			<xsd:import schemaLocation="back-office.xsd" namespace="http://xml.netbeans.org/schema/back-office"/>
		</xsd:schema>
	</types>
	<message name="WriteInputMessage">
		<part name="part1" element="ns0:record"/>
	</message>
	<portType name="BackOfficePT">
		<operation name="write">
			<input name="input1" message="tns:WriteInputMessage"/>
		</operation>
	</portType>
	<binding name="BackOfficeBinding" type="tns:BackOfficePT">
		<file:binding/>
		<operation name="write">
			<file:operation verb="write"/>
			<input name="input1">
				<file:message
                    fileName="output.txt"
                    encodingStyle="customencoder-1.0"
                    use="encoded"
                    part="part1"
                    addEOL="true"
                    recordDelimiter="LINE FEED"
                    multipleRecordsPerFile="true"/>
			</input>
		</operation>
	</binding>
	<service name="BackOfficeService">
		<port name="BackOfficeServicePort" binding="tns:BackOfficeBinding">
			<file:address fileDirectory="d:/temp"/>
		</port>
	</service>
	<plnk:partnerLinkType name="BackOfficeServiceLT">
		<plnk:role name="BackOffice" portType="tns:BackOfficePT"/>
	</plnk:partnerLinkType>
</definitions>

This WSDL uses a particular (not portable) binding, namely to the local filesystem. This binding is implemented by the OpenESB File BC. It works in conjunction with the annotated XML schema which was presented earlier.

As a final note concerning writing WSDLs: there is a large number of names, namespace URI’s and namespace prefixes to be made up. It will pay off to design some kind of naming convention.

Next: it’s about time to see some WS-BPEL code!

Previous pageNext page

One Comment

December 15, 2009 at 11:12 am BPEL_evaluator

1

Thanks for the example. I now heve a better understanding of correlation Keep up th good work!