BPEL4WS

We describe workflows and the workflow language BPEL4WS. We study the possibility of using workflows in multiagent enactment.

1 Workflows

1.1 Why Workflows?

Note:

Most large companies have “workflow experts” whose job is to develop the workflows that the business implements. For example, an insurance agency might have experts that determine how a claim is to be handled. These workflows are under constant revision since the business' requests and needs are constantly changing. The tools the companies above provide usually provide a GUI that the expert can use to draw workflow, similar to how one might draw a flowchart. The enactment engine of the tools take these workflows as input and execute them.

2 BPEL4WS

Note:

BPEL4WS was created jointly by Microsoft and IBM, along with others. Both companies started with workflow tools that wrote the workflows to files using their own propietary format. One of the goals for BPEL4WS was for it to be able to express most of the constructs that could be implemented with both tools, so that one could save a workflow with one one vendor's tool and read it back with another vendor's tool (in the same way that many browsers can read the same HTML files).

3 BPEL4WS Language Structure

3.1 PO Example

PO Workflow
<process name="purchaseOrderProcess" 
         targetNamespace="http://acme.com/ws-bp/purchase"
         xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
         xmlns:lns="http://manufacturing.org/wsdl/purchase">
   
   <partnerLinks>
      <partnerLink name="purchasing" 
               partnerLinkType="lns:purchasingLT"
               myRole="purchaseService"/>
      <partnerLink name="invoicing" 
               partnerLinkType="lns:invoicingLT"
               myRole="invoiceRequester"
               partnerRole="invoiceService"/>
      <partnerLink name="shipping" 
               partnerLinkType="lns:shippingLT"
               myRole="shippingRequester"
               partnerRole="shippingService"/>
      <partnerLink name="scheduling" 
               partnerLinkType="lns:schedulingLT"
               partnerRole="schedulingService"/>
   </partnerLinks>

   <variables>
      <variable name="PO" messageType="lns:POMessage"/>
      <variable name="Invoice" 
                 messageType="lns:InvMessage"/>
      <variable name="POFault" 
                 messageType="lns:orderFaultType"/>
      <variable name="shippingRequest" 
                 messageType="lns:shippingRequestMessage"/>
      <variable name="shippingInfo" 
                 messageType="lns:shippingInfoMessage"/>
      <variable name="shippingSchedule" 
                 messageType="lns:scheduleMessage"/>
   </variables>

   <faultHandlers>
      <catch faultName="lns:cannotCompleteOrder" 
             faultVariable="POFault">
         <reply   partnerLink="purchasing"
                  portType="lns:purchaseOrderPT" 
                  operation="sendPurchaseOrder"
                  variable="POFault" 
                  faultName="cannotCompleteOrder"/>
      </catch>
   </faultHandlers>
 
   <sequence>

      <receive partnerLink="purchasing" 
               portType="lns:purchaseOrderPT" 
               operation="sendPurchaseOrder" 
               variable="PO">
      </receive>

      <flow>

         <links>
            <link name="ship-to-invoice"/>
            <link name="ship-to-scheduling"/>
         </links>

         <sequence>
            <assign>
               <copy>
                  <from variable="PO" part="customerInfo"/>
                  <to variable="shippingRequest" 
                      part="customerInfo"/>
               </copy>
            </assign>
   
            <invoke  partnerLink="shipping" 
                     portType="lns:shippingPT" 
                     operation="requestShipping"
                     inputVariable="shippingRequest" 
                     outputVariable="shippingInfo">
               <source linkName="ship-to-invoice"/>
            </invoke>

            <receive partnerLink="shipping" 
                     portType="lns:shippingCallbackPT" 
                     operation="sendSchedule"
                     variable="shippingSchedule">
               <source linkName="ship-to-scheduling"/>
            </receive>

         </sequence>

         <sequence>

            <invoke  partnerLink="invoicing" 
                     portType="lns:computePricePT" 
                     operation="initiatePriceCalculation"
                     inputVariable="PO">
            </invoke>
            <invoke  partnerLink="invoicing" 
                     portType="lns:computePricePT" 
                     operation="sendShippingPrice"
                     inputVariable="shippingInfo">
               <target linkName="ship-to-invoice"/>
            </invoke>

            <receive partnerLink="invoicing" 
                     portType="lns:invoiceCallbackPT" 
                     operation="sendInvoice"
                     variable="Invoice"/>

         </sequence>

         <sequence>
            <invoke  partnerLink="scheduling" 
                     portType="lns:schedulingPT" 
                     operation="requestProductionScheduling"
                     inputVariable="PO">
            </invoke>
            <invoke  partnerLink="scheduling" 
                     portType="lns:schedulingPT" 
                     operation="sendShippingSchedule"
                     inputVariable="shippingSchedule">
               <target linkName="ship-to-scheduling"/>
            </invoke>
         </sequence>
      </flow>

      <reply partnerLink="purchasing" 
             portType="lns:purchaseOrderPT" 
             operation="sendPurchaseOrder" 
             variable="Invoice"/>
   </sequence>

</process>

3.2 General Structure

<process name="ncname" targetNamespace="uri" 
         queryLanguage="anyURI"?
         expressionLanguage="anyURI"?
         suppressJoinFailure="yes|no"?
         enableInstanceCompensation="yes|no"?
         abstractProcess="yes|no"?
         xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/">

  <partnerLinks>?
    <!-- Note: At least one role must be specified. -->
    <partnerLink name="ncname" partnerLinkType="qname" 
             myRole="ncname"? partnerRole="ncname"?>+
    </partnerLink>
  </partnerLinks>

  <partners>?
     <partner name="ncname">+
      <partnerLink name="ncname"/>+
   </partner>
  </partners>

  <variables>?
    <variable name="ncname" messageType="qname"?
                type="qname"? element="qname"?/>+ 
  </variables>

  <correlationSets>?
    <correlationSet name="ncname" properties="qname-list"/>+
  </correlationSets>

  <faultHandlers>?
    <!-- Note: There must be at least one fault handler or default. -->
    <catch faultName="qname"? faultVariable="ncname"?>*
      activity
    </catch>
    <catchAll>?
      activity
    </catchAll>
  </faultHandlers>

  <compensationHandler>?
    activity
  </compensationHandler>

  <eventHandlers>?
    <!-- Note: There must be at least one onMessage or onAlarm handler. -->
    <onMessage partnerLink="ncname" portType="qname"
               operation="ncname" variable="ncname"?>
      <correlations>?
        <correlation set="ncname" initiate="yes|no"?>+
      <correlations>
      activity
    </onMessage>
    <onAlarm for="duration-expr"? until="deadline-expr"?>*
      activity
    </onAlarm>
  </eventHandlers>
    
  activity
</process>

3.3 Receive

3.4 Reply

<reply partnerLink="ncname" portType="qname" operation="ncname"
       variable="ncname"? faultName="qname"?
       standard-attributes>
  standard-elements
  <correlations>?
     <correlation set="ncname" initiate="yes|no"?>+
  </correlations>
</reply>

3.5 Invoke

<invoke partnerLink="ncname" portType="qname" operation="ncname"
        inputVariable="ncname"? outputVariable="ncname"?
        standard-attributes>
  standard-elements
  <correlations>?
     <correlation set="ncname" initiate="yes|no"? 
                  pattern="in|out|out-in"/>+
  </correlations>
  <catch faultName="qname" faultVariable="ncname"?>*
    activity
  </catch>
  <catchAll>?
    activity
  </catchAll>
  <compensationHandler>?
    activity
  </compensationHandler>
</invoke>

<!--- for example -->
<invoke partnerLink="Seller" portType="SP:Purchasing" 
        operation="SyncPurchase" 
        inputVariable="sendPO" 
        outputVariable="getResponse">
  <compensationHandler>
      <invoke partnerLink="Seller" portType="SP:Purchasing" 
              operation="CancelPurchase" 
              inputVariable="getResponse"
              outputVariable="getConfirmation">
  </compensationHandler>
</invoke>

3.6 Assign

<assign standard-attributes>
  standard-elements
  <copy>+
    from-spec
    to-spec
  </copy>
</assign>

3.7 Throw

3.8 Wait

<wait (for="duration-expr" | until="deadline-expr") standard-attributes>
  standard-elements
</wait>

3.9 Empty

<empty standard-attributes>
  standard-elements
</empty>

3.10 Sequence

<sequence standard-attributes>
  standard-elementsactivity+
</sequence>

3.11 Switch

<switch standard-attributes>
  standard-elements
  <case condition="bool-expr">+
    activity
  </case>
  <otherwise>?
    activity
  </otherwise>
</switch>

<!-- for example -->

<switch xmlns:inventory="http://supply-chain.org/inventory" 
        xmlns:FLT="http://example.com/faults">
  <case condition= "bpws:getVariableProperty(stockResult,level) > 100">
    <flow>
       <!-- perform fulfillment work -->
    </flow>
  </case>
  <case condition="bpws:getVariableProperty(stockResult,level) >= 0">
    <throw faultName="FLT:OutOfStock" 
           variable="RestockEstimate"/>
  </case>
  <otherwise>
    <throw faultName="FLT:ItemDiscontinued"/>
  </otherwise>
</switch>

3.12 While

<while condition="bool-expr" standard-attributes>
   standard-elementsactivity
</while>

<!-- for example -->

<variable name="orderDetails" type="xsd:integer"/>
    ...
<while condition=
           "bpws:getVariableData(orderDetails) > 100">
  <scope>
    ...
  </scope>
</while>

3.13 Pick

<pick createInstance="yes|no"? standard-attributes>
  standard-elements
  <onMessage partnerLink="ncname" portType="qname"
             operation="ncname" variable="ncname"?>+
    <correlations>?
       <correlation set="ncname" initiate="yes|no"?>+
    </correlations>
    activity
  </onMessage>
  <onAlarm (for="duration-expr" | until="deadline-expr")>*
    activity
  </onAlarm>
</pick>
                
<!-- for example -->
<pick>
  <onMessage partnerLink="buyer"
                portType="orderEntry"
                operation="inputLineItem"
                variable="lineItem">
        <!-- activity to add line item to order -->
  </onMessage>
  <onMessage partnerLink="buyer"
                portType="orderEntry"
                operation="orderComplete"
                variable="completionDetail">
        <!-- activity to perform order completion -->
   </onMessage>

   <!-- set an alarm to go after 3 days and 10 hours -->
   <onAlarm for="'P3DT10H'">
        <!-- handle timeout for order completion  -->
   </onAlarm>
</pick>

3.14 Flow

<flow standard-attributes>
  standard-elements
  <links>?
    <link name="ncname">+
  </links>
  activity+
</flow>

<!-- for example -->
<flow>
  <links>
    <link name="XtoY"/>
    <link name="CtoD"/>
  </links>
  <sequence name="X">
     <source linkName="XtoY"/>
     <invoke name="A" .../>
     <invoke name="B" .../>
  </sequence>
  <sequence name"Y">
     <target linkName="XtoY"/>
     <receive name="C" ...>
       <source linkName="CtoD"/>
     </receive>
     <invoke name="E" .../>
  </sequence>
  <invoke partnerLink="D" ...>
    <target linkName="CtoD"/>
  </invoke>
</flow>

3.15 Scope

<scope variableAccessSerializable="yes|no" standard-attributes>
    standard-elements
    <variables>?

    </variables>
    <correlationSets>?

    </correlationSets>
    <faultHandlers>?

    </faultHandlers>
    <compensationHandler>?

    </compensationHandler>
    <eventHandlers>?
      ...
    </eventHandlers>
    activity
</scope>
                

3.16 Compensate

4 Process Instances

5 PartnerLinkType

6 Properties

<definitions name="properties"
      targetNamespace="http://example.com/properties.wsdl"
      xmlns:tns="http://example.com/properties.wsdl"
      xmlns:txtyp="http://example.com/taxTypes.xsd"
      xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
      xmlns="http://schemas.xmlsoap.org/wsdl/">

    <!-- define a correlation property -->
    <bpws:property name="taxpayerNumber"
                               type="txtyp:SSN"/>
    ...
</wsdl:definitions>

7 Variables

<complexType name="tAddress">
  <sequence>
    <element name="number" type="xsd:int"/>
    <element name="street" type="xsd:string"/>
    <element name="city" type="xsd:string"/>
    <element name="phone">
      <complexType>
        <sequence>
          <element name="areacode" type="xsd:int"/>
          <element name="exchange" type="xsd:int"/>
          <element name="number" type="xsd:int"/>
        </sequence>
      </complexType>
    </element>
  </sequence>
</complexType>

<element name = "address" type = "tAddress"/>

<!-- this message in the the .wsdl file -->
<message name="person" xmlns:x="http://tempuri.org/bpws/example">
  <part name="full-name" type="xsd:string"/>
  <part name="address" element="x:address"/>
</message>
<!-- -->

<variable name="c1" messageType="x:person"/>
<variable name="c2" messageType="x:person"/>
<variable name="c3" element="x:address"/>

<assign>
  <copy>
    <from variable="c1"/>
    <to variable="c2"/>
  </copy>
  <copy>
    <from variable="c1" part = "address"/>
    <to variable="c3"/>
  </copy>
</assign>                       

8 CorrelationSets

10 Loan Approval Example

<process name="loanApprovalProcess" 
         targetNamespace="http://acme.com/loanprocessing" 
         xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
         xmlns:lns="http://loans.org/wsdl/loan-approval"
         suppressJoinFailure="yes">

   <partnerLinks>
      <partnerLink name="customer" 
               partnerLinkType="lns:loanPartnerLinkType"
               myRole="loanService"/>
      <partnerLink name="approver" 
               partnerLinkType="lns:loanApprovalLinkType"
               partnerRole="approver"/>
      <partnerLink name="assessor" 
               partnerLinkType="lns:riskAssessmentLinkType"
               partnerRole="assessor"/>
   </partnerLinks>

   <variables>
     <variable name="request" 
                messageType="lns:creditInformationMessage"/>
     <variable name="risk" 
                messageType="lns:riskAssessmentMessage"/>
     <variable name="approval" 
                messageType="lns:approvalMessage"/>
     <variable name="error" 
                messageType="lns:errorMessage"/>
   </variables>

   <faultHandlers>
      <catch faultName="lns:loanProcessFault" 
             faultVariable="error">
         <reply   partnerLink="customer"
                  portType="lns:loanServicePT" 
                  operation="request"
                  variable="error" 
                  faultName="unableToHandleRequest"/>
      </catch>
   </faultHandlers>
                                                                  

   <flow>

      <links>
         <link name="receive-to-assess"/>
         <link name="receive-to-approval"/>
         <link name="approval-to-reply"/>
         <link name="assess-to-setMessage"/>
         <link name="setMessage-to-reply"/>
         <link name="assess-to-approval"/>
      </links>

      <receive partnerLink="customer" 
               portType="lns:loanServicePT" 
               operation="request" 
               variable="request" createInstance="yes">
         <source linkName="receive-to-assess"
            transitionCondition=
              "bpws:getVariableData('request','amount')< 10000"/>          
         <source linkName="receive-to-approval"
            transitionCondition=
              "bpws:getVariableData('request','amount')>=10000"/>
      </receive>

      <invoke  partnerLink="assessor" 
               portType="lns:riskAssessmentPT" 
               operation="check"
               inputVariable="request"  
               outputVariable="risk">
         <target linkName="receive-to-assess"/>
         <source linkName="assess-to-setMessage" 
            transitionCondition=
              "bpws:getVariableData('risk','level')='low'"/>
         <source linkName="assess-to-approval" 
            transitionCondition=
              "bpws:getVariableData('risk','level')!='low'"/>
      </invoke>

      <assign>
         <target linkName="assess-to-setMessage"/>
         <source linkName="setMessage-to-reply"/>
         <copy>
            <from expression="'yes'"/>
            <to variable="approval" part="accept"/>
         </copy>
      </assign>

      <invoke  partnerLink="approver" 
               portType="lns:loanApprovalPT" 
               operation="approve" 
               inputVariable="request" 
               outputVariable="approval">
         <target linkName="receive-to-approval"/>
         <target linkName="assess-to-approval"/>
         <source linkName="approval-to-reply" />
      </invoke>

      <reply   partnerLink="customer" 
               portType="lns:loanServicePT" 
               operation="request" 
               variable="approval">
         <target linkName="setMessage-to-reply"/>
         <target linkName="approval-to-reply"/>
      </reply>
   </flow>

</process>
                

11 Adaptive Multiagent Enactment of Workflows

URLs

  1. Business Process Execution Language for Web Services Version 1.1, http://www-106.ibm.com/developerworks/webservices/library/ws-bpel/
  2. Multiagent Systems with Workflows., http://jmvidal.cse.sc.edu/papers/vidal04a.pdf
  3. IBM WebSphere MQ Workflow, http://www-306.ibm.com/software/integration/wmqwf/
  4. Lotus Workflow, http://www.lotus.com/products/domworkflow.nsf
  5. Microsoft BizTalk Server, http://www.microsoft.com/biztalk/
  6. SAP, http://www.sap.com/
  7. SAP NetWeaver, http://www.sap.com/solutions/netweaver/index.asp

This talk available at http://jmvidal.cse.sc.edu/talks/bpel4ws/
Copyright © 2009 José M. Vidal . All rights reserved.

21 April 2004, 11:34AM