WSO2Con 2013 CFP Banner

Writing a simple WS-BPEL process for WSO2 BPS and Apache ODE

Discuss this article on Stack Overflow
By Denis Weerasiri
  • 11 Aug, 2009
  • Level:  Intermediate
  • Reads: 94275

In this article, Denis Weerasiri describes how to create and deploy a simple BPEL process which interacts with several partner services using WSO2 BPS and Apache ODE.

Denis Weerasiri
PhD Student
UNSW

Introduction

BPEL is the de-facto standard for modeling executable Web services orchestrations. It is an XML-based language used for the definition and execution of business, as well as scientific work flows using Web services. WSO2 Business Process Server (WSO2 BPS) and Apache Orchestration Director Engine(ODE) are two WS-BPEL compliant business process executable work-flow engines, which support composition of Web services by orchestrating service interactions.

This article by Denis Weerasiri describes how to create and deploy a simple BPEL process which interacts with several partner services, in WSO2 BPS and Apache ODE. It focuses on the basic functionalities such as: how to invoke partner services from a BPEL process, how to wait for a message from a client who invokes a BPEL process etc. A sample BPEL process called "FunctionProcess" is also attached here, with required sample partner services. All examples are based on the sample code attached here.

Table of Content

What is a business process?

What's BPEL?

Orchestration vs. Choreography
Abstract and Executable processes
Asynchronous and Synchronous communication in a BPEL process

Basic terms used in the BPEL terminology

BPEL Process definition
PartnerLinks, PartnerLinkTypes
Variables

About the example

How to deploy sample partner services and the BPEL process

How to establish a partner link with a Web service

How to invoke the BPEL process from a client

How to invoke a partner Web service from the BPEL process

How to reply to the client from the BPEL process

How to do basic variable manipulation in a BPEL process

How to Deploy and test the BPEL process

What is deploy.xml?
Structure of the process container

Summary

References

What is a business process?

Typically a "process" is a sequence of activities. Business process is a collection of related and structured activities or tasks, that produce a specific service or output. A process may have zero or more well-defined inputs and an out come. During the execution of the business process, it executes its sub-processes synchronously or asynchronously for producing the final output. During the execution, it may interact with both humans or equipment.

Simple bank loan approval process

Figure 1 - Simple bank loan approval process

In the business process illustrated above, a conventional bank loan process is depicted. Let's try to understand the basic building components of a business process based on the above example.

Banking Customer - A client who initiates the business process. The client may prepare all necessary inputs required for the initialization. In this example it is a "loan request".

Loan request - A well defined input that is used in the execution of the business process. It may contain details of the customer, account etc.

Receive request process - In this sub process, the input "loan request" may be verified to ensure it meets basic loan requirements such as verification of account details. As described earlier, this is a sub-process, that produces an output used internally during the execution of the business process.

Verification process - Actually, in the diagram, there is no a sub-process labelled as the "verification process". Here "verification process" means, the encapsulation of logical expressions used after the "receive request process". In this sub-process, you may notice some logic expressions are depicted in the business process diagram itself, such as "credit score < 750" and loan <= 50000 etc. On other hand we also can think of this sub-process as a single "receive request process", instead of depicting it as two logical expressions.

Bank employee - Here is a human interaction involved in the business process. In this case Bank employee sends an acknowledgement to the Bank customer. Or else this also can be considered as another sub-process.

Send acknowledgement- This is the final output which is sent back to the customer who initiated the business process.

What's BPEL?

BPEL is the industry standard for business process orchestration. It is an XML-based language used for the definition and execution of business processes as well as scientific workflows using Web services. In other words, BPEL is used to write business processes by composing Web services together with orchestration. The outcome is a composite Web service which is a composition of several Web services. Though these business processes may interact with humans, the WS-BPEL standard does not specify human interactions. As a result, a business process defined by WS-BPEL alone can not have human interactions but only with Web services.

Current standard of the BPEL specification was defined by OASIS[1] and is named WS-BPEL2.0[2].

In next immediate topics, we will cover a few basic terms used in relation to BPEL.

Orchestration vs. Choreography

Web services can be composed using two approaches: They are orchestration and choreography. In orchestration, there is a central director to coordinate the services. In contrast, choreography contains no central director and each contributing service should have an understanding of participant services.

For composing Web services for a business process, orchestration is a better option for reasons such as simpler process management, loose coupling between participating Web services, ease in error handling, standardization and so on.

Abstract and Executable processes

Business processes written using WS-BPEL can also be done in two ways based on the definition of the actual behavior required in the business processes. They are, abstract and executable business processes. Abstract processes are intended to hide some operational details of the process. So they do not include executable details like process flows etc. Executable business processes are used to model the actual implementation of the business process.

Abstract process is denoted under the "http://docs.oasis-open.org/wsbpel/2.0/process/abstract" namespace and Executable process is denoted under the "http://docs.oasis-open.org/wsbpel/2.0/process/executable" namespace. Additionally, there are syntactical differences between an abstract and an executable BPEL process.

Asynchronous and Synchronous communication in a BPEL process

BPEL processes can also be categorized based on how it invokes an operation of a partner service: synchronous and asynchronous. However, it is not possible to use both methods when invoking a partner service's operation, as it is dependent on the type of partner service operation also.

Asynchronous transmission - Suppose a BPEL process invokes a partner service. After this invokation of the partner process, the BPEL process will continue to carry on with its execution process while that partner service completes performing its operation. The BPEL process will receive a response from the partner service, when the partner service is completed.

Synchronous transmission - Suppose a BPEL process invokes a partner service. The BPEL process then waits for the partner service's operation to be completed, and responded. After receiving this completion response from the partner service, the BPEL process will continue to carry on its execution flow. This transmission does not apply for the In-Only operations defined in the WSDL of the partner service.

Usually you'll use asynchronous services for long-lasting operations and synchronous services for operations that return a result in a relatively short time. Typically, when you use asynchronous Web services, the BPEL process too is asynchronous.

 

Basic terms used in the BPEL terminology

BPEL Process definition

A BPEL process definition is a document or a template used to define a business process. As a  convention, a BPEL process definition file comes with a ".bpel" extension. In terms of service invocation, a BPEL process defines the sequence in which Web services should be invoked, and they can be invoked synchronously or asynchronously. In a typical Web service invocation scenario, what happens is that a BPEL process invokes the Web service with an input, and from the Web service it returns an output to the BPEL process. A synchronous partner service invocation can be depicted as follows:

partner service invocation in a BPEL process

Figure 2 - Synchronous partner service invocation

This InputVariable can be dependent on a previous Web service invocation, or, internally manipulated data within the BPEL process. The output from the Web service is not essential, as some  partner service operations do not return any values. Here, the ServicePartnerLink is the logical link between the BPEL process and the partner service.

Other than invoking a Web service, BPEL facilitates declaring variables, manipulating them, expressing conditional behaviors, construction of loops, fault handling etc.

The BPEL process definition starts with <process /> root level element, with the required namespace declarations and attributes as follows.

    <process name="name-Of-BPEL-Process"
        targetNamespace="URI"
        xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/executable"
        --- >
    </process>

Inside this root-level element, all the other required elements are defined. Those elements may be:

  1. <extensions />
  2. <import />
  3. <partnerLinks />
  4. <messageExchanges />
  5. <variables />
  6. <correlationSets />
  7. <faultHandlers />
  8. <eventHandlers />
  9. Activity Elements

The Activity Elements are used to model the business process. Activity elements can be <sequence />, <receive />, <reply />, <invoke />, <assign /> etc.

The latter part of this section describes on some of the root level elements which are essential when defining a simple BPEL process.

PartnerLinks, PartnerLinkTypes

BPEL processes use <partnerLinks /> to define partner links. A partner link is a logical link from a BPEL process to an external Web service, or to a client who invokes the business process. In real world situations, usually a business process designer uses existing Web services. Therefore, in order to create a partner link, first of all, a partner link type should be defined in the partner service. This is done by adding a <partnerLinkType /> in the partner service WSDL and by mentioning what roles are defined for one or both parties, and also the WSDL's portType to be used. After defining the partner link type, in the BPEL process a <partnerLink /> should be defined which specifies which partnerLinkType and the role type (myRole or partnerRole or both) to be used.

eg - In partner service WSDL

<plnk:partnerLinkType name="FunctionProcessService" xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype">
   <plnk:role name="FunctionProcessServicePortTypeRole" portType="tns:FunctionProcessServicePortType"/>
</plnk:partnerLinkType>

In BPEL process

<partnerLinks>
   ---
   <partnerLink name="FunctionProcessPartnerLink" 
                xmlns:tns="http://FunctionProcessService.wsdl" 
                partnerLinkType="tns:FunctionProcessService" 
                myRole="FunctionProcessServicePortTypeRole"/>
</partnerLinks>

By this <partnerLinks /> and the <partnerLinkType /> BPEL process maintains a clear relationship within the process and it makes easier to understand processes interact with multiple partner services. But actually in the deployment level of BPEL process, the deployment descriptor also required to maintain the peer-to-peer relationship with the partner service.  A more clarified example is being discussed later in this article.

Variables

In a BPEL process, variables are used to hold messages that could be an incoming message from a partner, outgoing message to a partner, data required to hold the state of a process instance (and are never exchanged with partners) etc. These are specified in <variable /> elements, inside <variables /> element.

eg -

<variables>
   <variable name="FunctionProcessServiceOperationOutput" xmlns:tns="http://FunctionProcessService.wsdl" messageType="tns:FunctionProcessServiceOperationResponse"/>
   <variable name="MultiplyOutput1" messageType="ns1:multiplyResponse"/>
   ---
</variables>

A more detailed example is discussed later on, in this article.

About the example

All examples described in this article are based on a simple BPEL process called "FunctionProcess", which implements the following mathematical function using a BPEL process and three Web services:

f(x,y) = [(x + y) * (x * y)]2

Here, three basic mathematical functions are implemented as Axis2 partner Web services (all three axis2 services archives are attached at the end of this article). The service class implementation is additionally included in the Axis2 service archive. Using this BPEL process, these three services will be invoked and the final value returned. The three basic mathematical functions are as follows:
    1. Add (x+y) - Implemented as AdderService
        This service will use two integers as input parameters, and return the addition as an integer

    2. Multiply (x*y) - Implemented as MupltiplierService
        This service will use two integers as input parameters, and return the multiplication as an integer

    3. Square (x2) - Implemented as SquareService
        This service will use an integer as the input parameter, and returns the square as an integer

In the BPEL process, when the two input parameters are received by the process, the following services needs to be invoked in the given sequence. The sequence is indicated as labels in the diagram. The operations (x+y) and (x*y) can be invoked first, and in parallel. Then the multiplication, and finally the square operation.

Mathemetical function

This process can be depicted as below.

BPEL diagram for FunctionProcess

Here the process flow occurs from top to bottom. From top to bottom the activities can be described as follows:

ReceiveRequest - This activity is waiting for a client to invoke the business process. Client needs to use the FunctionProcessService to send a message to the BPEL process. This is depicted with the blue arrow pointing from FunctionProcessService to ReceiveRequest.

Assign1-Activity - After ReceiveRequest activity, the message received is stored in a variable which should be specified in the ReceiveRequest activity. This variable contains two integers. According to the mathematical function we use, these two integers should be assigned separately to both the activities. They are InvokeAdderService and InvokeMultiplierService1. Thereafter, the two activities can invoke the corresponding partner Web services.

Flow1 - Here the both InvokeAdderService and InvokeMultiplierService1 are encapsulated. This means both invocations occur in parallel.

InvokeAdderService - This activity invokes the AdderService partner Web service. This is depicted with a blue arrow pointing from InvokeAdderService to AdderService.

Mathemetical function

InvokeMultiplierService1 - This invokes the MultiplierService partner Web service.

Mathemetical function


Assign2-Activity - After InvokeAdderService and InvokeMultiplierService1 are occurred then the two returned results must be assigned such that the InvokeMultiplierService2 use the two returned resultant integers as its input parameters. This is done in this activity.

InvokeMultiplierService2 - This invokes the MultiplierService partner Web service with the returned results from InvokeAdderService and InvokeMultiplierService1.

Mathemetical function


Assign3-Activity - This assigns the resultant integer from InvokeMultiplierService2 to InvokeSquareService's input variable .

InvokeSquareService - Invokes the partner Web service SquareService using the resultant integer from InvokeMultiplierService2 as an input parameter.

Mathemetical function


Assign4-Activity - Assigns the resultant integer from the InvokeSquareService to Reply1 activity.

Reply1 - This sends the callback from InvokeSquareService to the client via FunctionProcessService.

In this example there should be 6 files included in the BPEL process container which is used to deploy in a BPEL engine like WSO2 BPS as follows.

  • FunctionProcess.bpel - The BPEL process definition of the business process
  • FunctionProcessService.wsdl - The WSDL definition for the FunctionProcessService
  • AdderService.wsdl - The WSDL definition of the AdderService
  • MultiplierService.wsdl - The WSDL definition of the MultiplierService
  • SquareService.wsdl - The WSDL definition of the SquareService
  • deploy.xml - deployment descriptor. This file depend on the BPEL engine you use

You probably wonder why those WSDLs and a deploy.xml are included, instead of using only a BPEL process definition. In a nutshell, the reason is that without those files the BPEL engine can't figure out the operational level details of external services which interacts with BPEL process.
Note - You may need to modify concrete level information in the WSDLs based on your service deployment environment configurations.

How to deploy sample partner services and the BPEL process

In this example, the three partner services can be deployed as POJO Web services using Apache Axis2. Else, you can simply use the service container provided by Apache ODE and WSO2 BPS.
Based on the partner service deployment, concrete level information in the WSDLs in the BPEL process container should be modified.

eg - If you need to deploy the partner services inside the service container provided by Apache ODE, then just go ahead and put the .aar (axis2 archive) for each partner service (i.e. AdderService.aar, MultiplierService.aar and SquareService.aar) in %ODE_DEPLOYMENT_ROOT%/WEB-INF/services. Here %ODE_DEPLOYMENT_ROOT% is location of the ODE deployment.
To deploy the BPEL process, put the process container (i.e. FunctionProcess directory in FunctionProcess.zip) in %ODE_DEPLOYMENT_ROOT%/WEB-INF/processes.
Note: As services are deployed in the service container provided by Apache ODE, then the service EPR in partner services WSDLs should be modified based on the service container.

eg - In AdderService.wsdl "http://localhost:8080/ode/processes/AdderService" determines where the partner service is deployed.

<wsdl:service name="AdderService">
   <wsdl:port name="AdderServiceSOAP11port_http" binding="ns0:AdderServiceSOAP11Binding">
      <soap:address location="http://localhost:8080/ode/processes/AdderService"/>
   </wsdl:port>
   ---
</wsdl:service>

 

How to establish a partner link with a Web service

This section discusses on how to establish a logical link from a BPEL process to an external Web service. This is done by the <partnerLink /> element inside the <partnerLinks /> element in a BPEL process.

eg- In FunctionProcess.bpel

<partnerLinks>
   <partnerLink name="SquarePartnerLink" xmlns:ns2="http://SquareService.wsdl" 
                partnerLinkType="ns2:SquareServicePartnerlinkType" partnerRole="squareRole"/>
   <partnerLink name="FunctionProcessPartnerLink" xmlns:tns="http://FunctionProcessService.wsdl" 
                partnerLinkType="tns:FunctionProcessService" myRole="FunctionProcessServicePortTypeRole"/>
</partnerLinks>

Every Web service used in a particular BPEL process need a <partnerLink /> element to define which WSDL <portType /> to be exposed to the BPEL process.

Let's figure out step-by step how actually a <partnerLink /> element establishes a logical link between a BPEL process and a Web service.

  • In a <partnerLink /> element there are four attributes. Let's take the following element as an example.
<partnerLink name="SquarePartnerLink" xmlns:ns2="http://SquareService.wsdl" 
             partnerLinkType="ns2:SquareServicePartnerlinkType" partnerRole="squareRole"/>
  • name- the name of the partnerLink. This attribute value should be unique to a particular BPEL process as it is used in the BPEL process to represent a particular partner Web service.
  • xmlns:xx - This attribute value is used in the partnerLinkType attribute to determine in which Web service the value of partnerLinkType is defined.
       eg- In the above <partnerLink /> the value "SquareServicePartnerlinkType" is defined under the namespace of "http://SquareService.wsdl". This namespace must be defined in a <import /> element in the particular BPEL process. In a BPEL process, <import /> element is used to link WSDL definition or a XML Schema.
       eg - The following <import /> element defines which WSDL definition comes under "http://SquareService.wsdl" namespace.
    <import namespace="http://SquareService.wsdl" location="SquareService.wsdl" 
            importType="http://schemas.xmlsoap.org/wsdl/"/>

    So ultimately, this determines the value of the partnerLinkType attribute defined in SquareService.wsdl. However, this attribute is not essential if the namespace used in the partnerLinkType attribute value is defined in the <process /> element.
     
  • partnerLinkType - Value of this attribute is linked with the partner Web service's WSDL <partnerLinkType /> element. This value must be namespace qualified, as the namespace determines the WSDL definition where this <partnerLinkType /> element is defined. So there should be a <partnerLinkType> element defined in SquareService.wsdl.
       eg - In SquareService.wsdl it is defined as follows.
    <plink:partnerLinkType name="SquareServicePartnerlinkType">
       <plink:role name="squareRole" portType="ns0:SquareServicePortType"/>
    </plink:partnerLinkType>
    
    This <partnerLinkType /> is defined under the namespace xmlns:plink="http://docs.oasis-open.org/wsbpel/2.0/plnktype" as this element is not defined under WSDL schema.
  • partnerRole/myRole - In a <partnerLink /> element it should be specified myRole or the partnerRole, or both. In a <partnerLinkType /> , there can be upto two roles which determines different types of port types which are used in the BPEL process. The value in myRole attribute determines the role of the BPEL process itself. The value in partnerRole attribute defines the role of the partner Web service. If in the corresponding WSDL's <partnerLinkType /> element has only one role, then one attribute should be ignored.
        eg - In FunctionProcess.bpel, there are two <partnerLink /> as follows.
    <partnerLink name="SquarePartnerLink" xmlns:ns2="http://SquareService.wsdl" 
                 partnerLinkType="ns2:SquareServicePartnerlinkType" partnerRole="squareRole"/>
    <partnerLink name="FunctionProcessPartnerLink" xmlns:tns="http://FunctionProcessService.wsdl" 
                 partnerLinkType="tns:FunctionProcessService" myRole="FunctionProcessServicePortTypeRole"/>
    
    The SquarePartnerLink partnerLink has only a partnerRole attribute. So the corresponding Web service is a partner Web service which is invoked by the BPEL process. The FunctionProcessPartnerLink partnerLink has only a myRole attribute. So the corresponding Web service represents the BPEL process itself.
    This partnerRole/myRole attribute value is linked with the corresponding WSDL's <plink:partnerLinkType /> element's <plink:role> element.
        eg -  In FunctionProcess.bpel
    <partnerLink name="SquarePartnerLink" xmlns:ns2="http://SquareService.wsdl" 
                 partnerLinkType="ns2:SquareServicePartnerlinkType" partnerRole="squareRole"/>
    
       In SquareService.wsdl
    <plink:partnerLinkType name="SquareServicePartnerlinkType">
       <plink:role name="squareRole" portType="ns0:SquareServicePortType"/>
    </plink:partnerLinkType>
    
    This <plink:role> has a portType attribute whose value determines a set of Web service operations. If the particular <plink:role /> is mentioned as a myRole in the <partnerLink /> element in the BPEL process, then the operations defined in the corresponding portType attribute value will be used to call BPEL process from an external client. If the particular <plink:role /> is mentioned as a partnerRole in the <partnerLink /> element in the BPEL process, then the operations defined in the corresponding portType attribute value will be used to invoke the partner Web services by the BPEL process.
       eg - In SquareService.wsdl, the SquareServicePortType is defined as follows.
    <wsdl:portType name="SquareServicePortType">
       <wsdl:operation name="square">
          <wsdl:input message="ns0:squareRequest" wsaw:Action="urn:square"/>
          <wsdl:output message="ns0:squareResponse" wsaw:Action="urn:squareResponse"/>
       </wsdl:operation>
    </wsdl:portType>    
    

    So the square operation will be used by BPEL process to invoke this partner Web Service. eg - In FunctionProcess.bpel

    <invoke name="InvokeSquareService" partnerLink="SquarePartnerLink" 
            operation="square" xmlns:ns2="http://SquareService.wsdl" portType="ns2:SquareServicePortType" 
            inputVariable="SquareInput" outputVariable="SquareOutput"/>
    

 

How to invoke the BPEL process from a client

As the above section described, a Web service can be a partner Web service or a Web service that represents the role of the BPEL process. So if a <partnerLink /> defined in the BPEL process has a myRole attribute, then the corresponding Web service will used by external clients to invoke the BPEL process.

Let's figure out step by step on how an external client can invoke a particular BPEL process.

When a client sends a message to the BPEL process, it should be waiting for the message. This input message is defined inside a <receive /> activity element by specifying the partnerLink and the operation attributes, such that the <receive /> waits for the correct input message. The <receive /> can be used as a top level element in the BPEL process or as a child element inside a structure activity like <sequence /> .

   eg - In FunctionProcess.bpel

<sequence>
   <receive name="ReceiveRequest" createInstance="yes" partnerLink="FunctionProcessPartnerLink" 
            operation="FunctionProcessServiceOperation" xmlns:tns="http://FunctionProcessService.wsdl" 
            portType="tns:FunctionProcessServicePortType" variable="FunctionProcessServiceOperationInput"/>
   ---
</sequence>

Let's figure out what those attributes are.

  • name - name of the Element
  • createInstance - determines whether to create a process instance when a message is received, or not.
  • partnerLink - an essential attribute in a <receive /> element. This determines the WSDL's portType to be chosen based on the partnerLinkType attribute and the myRole attributes defined in the particular <partnerLink /> element.
       eg - In FunctionProcess.bpel
    <partnerLinks>
       <partnerLink name="FunctionProcessPartnerLink" xmlns:tns="http://FunctionProcessService.wsdl"
                    partnerLinkType="tns:FunctionProcessService" myRole="FunctionProcessServicePortTypeRole"/>
       ---
    </partnerLinks>
    <sequence>
       <receive name="ReceiveRequest" createInstance="yes" partnerLink="FunctionProcessPartnerLink" 
                operation="FunctionProcessServiceOperation" xmlns:tns="http://FunctionProcessService.wsdl" 
                portType="tns:FunctionProcessServicePortType" variable="FunctionProcessServiceOperationInput"/>
       ---
    </sequence>    
        In FunctionProcessService.wsdl
    <portType name="FunctionProcessServicePortType">
       <operation name="FunctionProcessServiceOperation">
          <input name="input1" message="tns:FunctionProcessServiceOperationRequest"/>
          <output name="output1" message="tns:FunctionProcessServiceOperationResponse"/>
       </operation>
    </portType>
    ----
    <plnk:partnerLinkType name="FunctionProcessService">
       <plnk:role name="FunctionProcessServicePortTypeRole" portType="tns:FunctionProcessServicePortType"/>
    </plnk:partnerLinkType>
    
  • operation - an essential attribute and determines which operation's message is the matching input message. According to the above example FunctionProcessServiceOperation is the operation and the message should be in the type of FunctionProcessServiceOperationRequest.
  • variable - where the incoming message will be stored as a BPEL process variable for further manipulation in the BPEL process execution. This variable should be defined in a <variable /> inside <variables /> element.
       eg - In FunctionProcess.bpel
    <variables>
       <variable name="FunctionProcessServiceOperationInput" xmlns:tns="http://FunctionProcessService.wsdl" 
                 messageType="tns:FunctionProcessServiceOperationRequest"/>
    </variables>
    
    As well the messageType attribute value must compatible with the input message type of the particular WSDL's operations.

So ultimately <receive /> waits for a client to invoke the particular operation, and stores the incoming message in the particular variable.

 

How to invoke a partner Web service from the BPEL process

This is done by <invoke /> element that specifies the partnerLink and the operation to be invoked as attributes inside it, and is very similar to the <receive /> element. The <invoke /> can be used as a top level element in the BPEL process or as a child element inside a structure activity like <sequence /> .

   eg - In FunctionProcess.bpel

<invoke name="InvokeSquareService" partnerLink="SquarePartnerLink" operation="square" 
        xmlns:ns2="http://SquareService.wsdl" portType="ns2:SquareServicePortType" 
        inputVariable="SquareInput" outputVariable="SquareOutput"/>

Let's figure out what those attributes are.

  • name - name of the invoke element
  • partnerLink - an essential attribute and determines which WSDL's portType to be used.
       eg - In FunctionProcess.bpel
    <partnerLinks>
       <partnerLink name="SquarePartnerLink" xmlns:ns2="http://SquareService.wsdl" 
                    partnerLinkType="ns2:SquareServicePartnerlinkType" partnerRole="squareRole"/>
       ----
    </partnerLinks>
    <sequence>
       <invoke name="InvokeSquareService" partnerLink="SquarePartnerLink" operation="square"
               xmlns:ns2="http://SquareService.wsdl" portType="ns2:SquareServicePortType"
               inputVariable="SquareInput" outputVariable="SquareOutput"/>
       ----
    </sequence>
        In SquareService.wsdl
    <wsdl:portType name="SquareServicePortType">
       <wsdl:operation name="square">
          <wsdl:input message="ns0:squareRequest" wsaw:Action="urn:square"/>
          <wsdl:output message="ns0:squareResponse" wsaw:Action="urn:squareResponse"/>
       </wsdl:operation>
    </wsdl:portType>
    ---
    <plink:partnerLinkType name="SquareServicePartnerlinkType">
       <plink:role name="squareRole" portType="ns0:SquareServicePortType"/>
    </plink:partnerLinkType>
    
  • operation - an essential attribute, determines which operation to be invoked in the particular WSDL's portType, which was determined by partnerLink attribute previously.

    eg - In the above example "square" is defined in the "SquareServicePortType". So the outgoing message from the BPEL engine and the incoming message to the BPEL engine, should be compatible with the message types defined in <wsdl:input /> and <wsdl:output />, respectively.

  • inputVariable/outputVariable - values of these attributes determines the outgoing and incoming messages from the partner Web service respectively. So the variable specified by the inputVariable attribute value must be compatible with the message type specified in the <wsdl:input /> element of the particular WSDL's operation.

    The variable specified by the outputVariable attribute value must be compatible with the message type specified in the <wsdl:output /> element of the particular WSDL's operation.

        eg - In the FunctionProcess.bpel
    <variables>
       ---
       <variable name="SquareInput" xmlns:ns2="http://SquareService.wsdl" messageType="ns2:squareRequest"/>      
       <variable name="SquareOutput" xmlns:ns2="http://SquareService.wsdl" messageType="ns2:squareResponse"/>    
       ---     
    </variables>
    ---
    <sequence>
       <invoke name="InvokeSquareService" partnerLink="SquarePartnerLink" operation="square" 
               xmlns:ns2="http://SquareService.wsdl" portType="ns2:SquareServicePortType" 
               inputVariable="SquareInput" outputVariable="SquareOutput"/>
       ---
    </sequence>
        In SquareService.wsdl
    <wsdl:portType name="SquareServicePortType">
       <wsdl:operation name="square">
          <wsdl:input message="ns0:squareRequest" wsaw:Action="urn:square"/>
          <wsdl:output message="ns0:squareResponse" wsaw:Action="urn:squareResponse"/>
       </wsdl:operation>
    </wsdl:portType>
    ---
    <plink:partnerLinkType name="SquareServicePartnerlinkType">
       <plink:role name="squareRole" portType="ns0:SquareServicePortType"/>
    </plink:partnerLinkType>

 

How to reply to the client from the BPEL process

When a client invokes a BPEL process by sending an input message which is received in the <receive /> element, the BPEL engine executes subsequent activities defined after that <receive /> element. Those subsequent activities may be <assign /> , <invoke /> etc. After a BPEL process invokes a Web service, the BPEL process may then need to respond to the client with a valid result. This is modeled by the <reply /> element by specifying the partnerLink and the operation attribute values. The <reply /> element can be used as a top level element in the BPEL process, or as a child element inside a structured activity like <sequence />.

   eg - In FunctionProcess.bpel

<reply name="Reply1" partnerLink="FunctionProcessPartnerLink" operation="FunctionProcessServiceOperation"
       xmlns:tns="http://FunctionProcessService.wsdl" portType="tns:FunctionProcessServicePortType" 
       variable="FunctionProcessServiceOperationOutput"/>

If the result is to be sent to the same client who sends an input message, then those partnerLink and the operation attribute values must be similar to partnerLink and the operation attribute values specified in the particular <receive /> element respectively.

   eg - In FunctionProcess.bpel

<sequence>
   <receive name="ReceiveRequest" createInstance="yes" partnerLink="FunctionProcessPartnerLink" 
            operation="FunctionProcessServiceOperation" xmlns:tns="http://FunctionProcessService.wsdl" 
            portType="tns:FunctionProcessServicePortType" variable="FunctionProcessServiceOperationInput"/>
   ---    
   <reply name="Reply1" partnerLink="FunctionProcessPartnerLink" operation="FunctionProcessServiceOperation" 
          xmlns:tns="http://FunctionProcessService.wsdl" portType="tns:FunctionProcessServicePortType" 
          variable="FunctionProcessServiceOperationOutput"/>
</sequence>     

Let's figure out what those attributes are.

  • name - name of the reply element
  • partnerLink - an essential attribute which determines which WSDL's portType is used to send a reply message to the client.
       eg - In FunctionProcess.bpel
    <partnerLinks>
       ---
       <partnerLink name="FunctionProcessPartnerLink" xmlns:tns="http://FunctionProcessService.wsdl"
                    partnerLinkType="tns:FunctionProcessService" myRole="FunctionProcessServicePortTypeRole"/>
    </partnerLinks>  
    ---
    <sequence>
       --- 
       <reply name="Reply1" partnerLink="FunctionProcessPartnerLink"
              operation="FunctionProcessServiceOperation" xmlns:tns="http://FunctionProcessService.wsdl"
              portType="tns:FunctionProcessServicePortType" variable="FunctionProcessServiceOperationOutput"/>
    </sequence>     
    
        In FunctionProcessService.wsdl
    <portType name="FunctionProcessServicePortType">
       <operation name="FunctionProcessServiceOperation">
          <input name="input1" message="tns:FunctionProcessServiceOperationRequest"/>
          <output name="output1" message="tns:FunctionProcessServiceOperationResponse"/>
       </operation>
    </portType>
    ---
    <plnk:partnerLinkType name="FunctionProcessService">
       <plnk:role name="FunctionProcessServicePortTypeRole" portType="tns:FunctionProcessServicePortType"/>
    </plnk:partnerLinkType>
    
  • code class="prettyprint">operation - an essential attribute which determines which operation to be used in the particular WSDL's portType which is determined by code class="prettyprint">partnerLink attribute previously.
       eg - According to the above example code class="prettyprint">FunctionProcessServiceOperation is the operation and the message should be in the type of code class="prettyprint">FunctionProcessServiceOperationResponse.
  • variable - this variable determines the outgoing message value. So the message type of this attribute value must be compatible with the message type specified in the <wsdl:output /> element of the particular WSDL's operation.
       eg - In FunctionProcess.bpel
    <variables>
       <variable name="FunctionProcessServiceOperationOutput" xmlns:tns="http://FunctionProcessService.wsdl"
                 messageType="tns:FunctionProcessServiceOperationResponse"/>
       ---
    </variables> 
    ---       
    <sequence>
       ---
       <reply name="Reply1" partnerLink="FunctionProcessPartnerLink" operation="FunctionProcessServiceOperation"
              xmlns:tns="http://FunctionProcessService.wsdl" portType="tns:FunctionProcessServicePortType" 
              variable="FunctionProcessServiceOperationOutput"/>
    </sequence>

       eg - In FunctionProcessService.wsdl
    <portType name="FunctionProcessServicePortType">
       <operation name="FunctionProcessServiceOperation">
          <input name="input1" message="tns:FunctionProcessServiceOperationRequest"/>
          <output name="output1" message="tns:FunctionProcessServiceOperationResponse"/>
       </operation>
    </portType>
    ---
    <plnk:partnerLinkType name="FunctionProcessService">
       <plnk:role name="FunctionProcessServicePortTypeRole" portType="tns:FunctionProcessServicePortType"/>
    </plnk:partnerLinkType> 
    

 

How to do basic variable manipulation in a BPEL process

This section describes about how the data handling takes place in a BPEL process using variables. BPEL process variable are defined with <variable /> element inside the <variables /> element.
    eg - In FunctionProcess.bpel

<variables>
   ---
   <variable name="FunctionProcessServiceOperationInput" xmlns:tns="http://FunctionProcessService.wsdl" 
             messageType="tns:FunctionProcessServiceOperationRequest"/>
   ---
</variables>

Let's figure out what those attributes are.

  • name - name of the variable
  • messageType - type of the variable. This type is defined as a XML Schema.
       eg - According to the following example FunctionProcessServiceOperationInput variable can hold an element which is Schema compatible with the functionProcessServiceRequest defined in FunctionProcessService.wsdl.
          In FunctionProcess.bpel
    <variables>
       ---
       <variable name="FunctionProcessServiceOperationInput" xmlns:tns="http://FunctionProcessService.wsdl"
                 messageType="tns:FunctionProcessServiceOperationRequest"/>
       ---
    </variables> 

          In FunctionProcessService.wsdl

    <wsdl:types>
       <xsd:schema xmlns:ns="http://ws.apache.org/axis2" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://www.example.org/messages">
          <xsd:element name="functionProcessServiceRequest">
             <xsd:complexType>
                <xsd:sequence>
                   <xsd:element minOccurs="0" name="param0" type="xsd:int"/>
                   <xsd:element minOccurs="0" name="param1" type="xsd:int"/>
                </xsd:sequence>
             </xsd:complexType>
          </xsd:element>
       </xsd:schema>
    </wsdl:types>
    ---
    <message name="FunctionProcessServiceOperationRequest">
       <part name="functionProcessServiceRequest" element="msgs:functionProcessServiceRequest"/>
    </message>

    In BPEL terminology, variables are used to hold messages that may be coming in from a partner, an outgoing message to a partner, data required to hold the state of process instances (and may never exchanged with partners) etc.

  • to hold an incoming message from a partner service or an external client,
       eg - In FunctionProcess.bpel
    <sequence>
       ---  
       <receive name="ReceiveRequest" createInstance="yes" partnerLink="FunctionProcessPartnerLink"
                operation="FunctionProcessServiceOperation" xmlns:tns="http://FunctionProcessService.wsdl"
                portType="tns:FunctionProcessServicePortType" variable="FunctionProcessServiceOperationInput"/>
       ---
       <invoke name="InvokeSquareService" partnerLink="SquarePartnerLink" operation="square"
               xmlns:ns2="http://SquareService.wsdl" portType="ns2:SquareServicePortType"
               inputVariable="SquareInput" outputVariable="SquareOutput"/>
       ---
    </sequence>
    

    Here the FunctionProcessServiceOperationInput variable is used to hold the incoming message from the external client and SquareOutput is used to hold the incoming message from a partner Web service.

  • to hold the outgoing message to a partner service or an external client
       eg - In FunctionProcess.bpel
    <sequence>
       ---
       <invoke name="InvokeSquareService" partnerLink="SquarePartnerLink" operation="square" 
               xmlns:ns2="http://SquareService.wsdl" portType="ns2:SquareServicePortType"
               inputVariable="SquareInput" outputVariable="SquareOutput"/>
       ---
       <reply name="Reply1" partnerLink="FunctionProcessPartnerLink" operation="FunctionProcessServiceOperation"
              xmlns:tns="http://FunctionProcessService.wsdl" portType="tns:FunctionProcessServicePortType" 
              variable="FunctionProcessServiceOperationOutput"/>
    </sequence>
    

    Here the SquareInput variable is used to hold the outgoing message to a partner Web service and FunctionProcessServiceOperationOutput is used to hold the outgoing message to an external client.

  • Another major usage of variables is for internal data manipulation among variables. This is basically done by the <assign /> element as follows.
    <assign /> element contains <copy /> child element which are used to copy data between variables.
       eg - In FunctionProcess.bpel
    <invoke name="InvokeMultiplierService2" partnerLink="MultiplierPartnerLink"
            operation="multiply" portType="ns1:MultiplierServicePortType"
            inputVariable="MultiplyInput1" outputVariable="MultiplyOutput1"/>
    <assign name="Assign3">
       <copy>
          <from>
             <literal xml:space="preserve">
                <tns:square xmlns:tns="http://ws.apache.org/axis2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                   <tns:param0></tns:param0>
                </tns:square>
             </literal>
          </from>
          <to part="parameters" variable="SquareInput">
          </to>
       </copy>
       <copy>
          <from>$MultiplyOutput1.parameters/ns4:return</from>
          <to>$SquareInput.parameters/ns4:param0</to>
       </copy>
    </assign>
    <invoke name="InvokeSquareService" partnerLink="SquarePartnerLink"
            operation="square" xmlns:ns2="http://SquareService.wsdl" portType="ns2:SquareServicePortType" 
            inputVariable="SquareInput" outputVariable="SquareOutput"/>

    Here what happens is that the first <invoke /> element invokes the multiply operation in MultiplierService, and the returned value is held in the MultiplyOutput1 variable. Then in the <assign /> element MultiplyOutput1 variable value is copy pasted to the SquareInput variable. Then the SquareInput variable is used as the inputVariable when invoking SquareService.

    In the <assign /> element two <copy /> elements are used. First, it is used to initialize the variable which does not contain any value yet. If attempted to paste a value to an uninitialized variable, BPEL engine would return a {http://docs.oasis-open.org/wsbpel/2.0/process/executable}selectionFailure fault.
    Then in the second <copy /> element, actual data manipulation occurs.

In the next section the above usages are elaborated descriptively.

  • How to initialize a variable
       eg - In FunctionProcess.bpel
    <assign name="Assign3">
       <copy>
          <from>
             <literal xml:space="preserve">
                <tns:square xmlns:tns="http://ws.apache.org/axis2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                   <tns:param0></tns:param0>
                </tns:square>
             </literal>
          </from>
          <to part="parameters" variable="SquareInput">
          </to>
       </copy>
       ---
    </assign>

    To initialize a variable to a known data type, we use <literal /> inside <from /> element. Inside  <literal /> element, the XML element to be initialized can be placed. The Schema of this XML element should be compatible with the messageType of the variable to be initialized.
       eg - Here the XML element defined inside <literal /> element in the above example is schema compatible with the following square XML schema defined in SquareService.wsdl.
          In FunctionProcess.bpel

    <variables>
       ---
       <variable name="SquareInput" xmlns:ns2="http://SquareService.wsdl" 
                 messageType="ns2:squareRequest"/>
       ---
    </variables>
    

          In SquareService.wsdl

    <wsdl:types>
       <xs:schema xmlns:ns="http://ws.apache.org/axis2" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://ws.apache.org/axis2">
          <xs:element name="square">
             <xs:complexType>
                <xs:sequence>
                   <xs:element minOccurs="0" name="param0" type="xs:int"/>
                </xs:sequence>
             </xs:complexType>
          </xs:element>
          ---
       </xs:schema>
    </wsdl:types>
    <wsdl:message name="squareRequest">
       <wsdl:part name="parameters" element="ns2:square"/>
    </wsdl:message>
    

    Then, in the <to /> element the variable and part of the message to be initialized are specified.
       eg - In FunctionProcess.bpel

    <variables>
       ---
       <variable name="SquareInput" xmlns:ns2="http://SquareService.wsdl"
                 messageType="ns2:squareRequest"/>
       ---
    </variables>
    ---
    ---
    <copy>
       <from>
          <literal xml:space="preserve">
             <tns:square xmlns:tns="http://ws.apache.org/axis2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <tns:param0></tns:param0>
             </tns:square>
          </literal>
       </from>
       <to part="parameters" variable="SquareInput">
       </to>
    </copy>
    

          In SquareService.wsdl

    <wsdl:message name="squareRequest">
       <wsdl:part name="parameters" element="ns2:square"/>
    </wsdl:message>
    
  • How to the data manipulation happen
       eg - In the FunctionProcess.bpel
    <assign name="Assign3">
       ---
       <copy xmlns:ns4="http://ws.apache.org/axis2">
          <from>$MultiplyOutput1.parameters/ns4:return</from>
          <to>$SquareInput.parameters/ns4:param0</to>
       </copy>
    </assign>
    

    Here, an XML element of one variable value of MultiplyOutput1 is mapped with another Schema compatible XML element of  SquareInput variable value as follows.

    $MultiplyOutput1.parameters/ns4:return $SquareInput.parameters/ns4:param0
    <parameters>
       <multiplyResponse xmlns="http://ws.apache.org/axis2">
          <return>48</return>
       </multiplyResponse>
    </parameters>
    <parameters>
       <square xmlns="http://ws.apache.org/axis2">
          <param0></param0>
       </square>
    </parameters>

 

How to Deploy and test the BPEL process

After implementing the BPEL process and linking it with the partner Web services, the last step is to deploy the BPEL process in a BPEL engine. This phase may differ from one BPEL engine to the next. In this section the deployment process elaborated is based on two open source BPEL engines. They are:
    1. WSO2 BPS (WSO2 Business Process Server)
    2. Apache ODE (
Apache Orchestration Director Engine)

Both of them have some similarities and differences in deploying a business process. The similarities are that both use the same process container structure and the deployment descriptor (deploy.xml).

The difference is in the way of deploying the final process container. WSO2 BPS requires a compressed process container into ZIP format. Apache ODE uses a process container itself to deploy the business process or the ODE Web console. A ZIP archive of the process container can also be uploaded to deploy the process.

What is deploy.xml?

WSO2 BPS and Apache ODE uses deploy.xml to configure one or several processes to use specific services. Every partner link used with a <receive /> activity must be matched with a <provide /> element, and every partnerLink used in an <invoke /> activity must be matched with an <invoke /> element in deploy.xml. Without a deploy.xml, a BPEL engine cannot figure the concrete level details of the partner services. In the deploy.xml, the <service /> element determines the concrete level details of all the partner services that interacts with the BPEL process.

   eg- deploy.xml

<?xml version="1.0" encoding="UTF-8"?>
<deploy xmlns="http://www.apache.org/ode/schemas/dd/2007/03" xmlns:FunctionProcess.bpel="http://FunctionProcess.bpel" 
        xmlns:FunctionProcessService.wsdl="http://FunctionProcessService.wsdl" xmlns:AdderService.wsdl="http://AdderService.wsdl" 
        xmlns:MultiplierService.wsdl="http://MultiplierService.wsdl" xmlns:SquareService.wsdl="http://SquareService.wsdl">
  <process name="FunctionProcess.bpel:FunctionProcess">
    <process-events generate="all"/>
    <provide partnerLink="FunctionProcessPartnerLink">
      <service name="FunctionProcessService.wsdl:FunctionProcessServiceService" port="FunctionProcessServicePort"/>
    </provide>
    <invoke partnerLink="SquarePartnerLink">
      <service name="SquareService.wsdl:SquareService" port="SquareServiceSOAP11port_http"/>
    </invoke>
    <invoke partnerLink="MultiplierPartnerLink">
      <service name="MultiplierService.wsdl:MultiplierService" port="MultiplierServiceSOAP11port_http"/>
    </invoke>
    <invoke partnerLink="AdderPartnerLink">
      <service name="AdderService.wsdl:AdderService" port="AdderServiceSOAP11port_http"/>
    </invoke>
  </process>
</deploy>

Here you may notice, that every process and a service is namespace qualified, and locations of each .bpel or .wsdl are not mentioned. deploy.xml supplies binding information for each partnerLink, to create WSDL services with the <service /> element for each <provide /> and <invoke /> element.
During the deployment of a process in the BPEL engine, it loads all required documents from the deployment descriptor.

Structure of the process container

In both WSO2 BPS and Apache ODE, the exact same flat file structure is used for a process container. XSDs may be contained in directories inside the process container.
    eg - In the FunctionProcess process container.
            FunctionProcess
               |->AdderService.wsdl
               |->deploy.xml
               |->FunctionProcess.bpel
               |->FunctionProcessService.wsdl
               |->MultiplierService.wsdl
               |->SquareService.wsdl

 

Summary


This article focused on the basic features offered in WS-BPEL 2.0 specification, and not on advanced concepts such as correlation, fault handling, activity dependency management etc. Therefore, it is only a beginner's guide to enterprise level business process development.

References

[1] - OASIS (Organization for the Advancement of Structured Information Standards)-http://www.oasis-open.org

[2] - Web Services Business Process Execution Language Version 2.0 - http://docs.oasis-open.org/wsbpel/2.0/OS/wsbpel-v2.0-OS.html

WSO2 BPS - http://wso2.org/projects/bps

Apache ODE - http://ode.apache.org/

Author

Denis Weerasiri is an undergraduate from University of Moratuwa. ddweerasiri AT gmail DOT com

http://ddweerasiri.blogspot.com/

 

AttachmentSize
FunctionProcess.zip6.08 KB
AdderService.aar1.23 KB
MultiplierService.aar1.13 KB
SquareService.aar1.1 KB