Skip to main content

Use RosettaNet-based Web services, Part 4: BPEL4WS and RosettaNet

Building reliable asynchronous processes with BPEL4WS

Suhayl Masud (SuhaylA@DifferentThinking.com), Founder and Lead Architect, Different Thinking
Suhayl Masud is the president of Different Thinking, a consulting firm that enables organizations to understand and conduct electronic business, by providing training, architecture, and application construction services. Suhayl is also the co-founder of Agile Webservices, providing Policy Based Computing solutions. Suhayl's experience includes consulting as the lead technical architect for RosettaNet, where he helped define the next generation of e-business process standards. Suhayl would love to hear from you at: SuhaylA@DifferentThinking.com

Summary:  Simply sending SOAP based messages between machines is not really "doing Web services" -- this is a limited view which obscures the larger picture. To conduct business electronically, you need technology that encourages you to think and act in ways in which business is conducted in the physical world. Web services are an important first step to encourage such thinking and, in this article, Suhayl describes how executable business processes can be created using BPEL4WS.

Date:  30 Sep 2003
Level:  Intermediate
Activity:  862 views

Exploring BPEL4WS

The Business Process Execution Language for Web Services (BPEL4WS) can be used to create e-business dialogues by "composing" new and previously defined Web services. BPEL4WS comes with several complimentary specifications (WS-Transaction and WS-Coordination) that take a BPEL4WS process further by adding more transaction support, and providing the ability for processes to span different platforms, systems, and execution engines.

BPEL4WS defines the choreography in a Web service, the roles of the interacting business partners, and may include advanced features like exception and compensation handling for actions already performed. BPEL4WS processes are not limited to interacting only with other BPEL4WS processes; they can interact with new and previously defined Web services on any platform running within, or outside, a BPEL4WS environment.

BPEL4WS components

In this section, I will briefly describe some components of BPEL4WS. For a more detailed description, please see the BPEL4WS series cited in the resources. You may find it helpful to refer to Figure 1 while you are reading through this section.


Figure 1. The process element definition in BPEL4WS from the schema design view of XMLSPY
Figure 1. The process element definition in BPEL4WS from the schema design view of XMLSPY

Process

There are two types of processes defined in BPEL4WS:

  1. Abstract processes which are the equivalent of defining public processes in an e-business dialogue, and
  2. Executable processes which run within the organization.

The main difference between the two processes is that abstract processes cannot be executed; they are utilized as an agreement between two partners about how they will interact in an e-business dialogue. The abstract processes only define public processes, and do not include what each organization does internally to conduct those public processes.

The executable processes on the other hand, are designed for executing business processes within an organization. Executable processes can compose together several Web services, tie in business logic, and access sensitive data, to achieve business goals for the organization.

Partners

At a conceptual level, a BPEL4WS process interacts with partners to receive, invoke, and reply to activities. These partners can be Web services within the organization or Web services at the business partner’s organization. A process definition begins with describing what parties (Web services) are involved and what roles they play. The most important part of the partner description is the service link type; it is a mechanism used to tie the Partner description to the operations the partners can perform from the WSDL definition.

Containers

The BPEL4WS process uses containers to store state information like temporary variables, or incoming and outgoing messages. A container is really a WSDL message type and it can be defined as an input or output container within invoke, receive, and reply activities.

Correlation Sets

A correlation set makes it possible for messages to be addressed to the correct port Type, and more importantly, the correct instance of the process. For example, assume that Organization A is conducting several purchase order processes with Organization B. When Organization B accepts a purchase order, this signal has to go to the correct purchase order process instance at Organization A, otherwise Organization A will make an incorrect assumption about which business request has been accepted.

Fault Handlers, Compensation Handlers, and Scope

When a fault occurs at a WSDL port, it may fire off a fault message. This fault message reaches the BPEL4WS process, which uses fault handlers to determine how to recover from the fault. One possible recovery option is to "undo" what the process has done so far. This recovery depends on how far the process had progressed when the fault occurred, and the best mechanism available to use the scope structured activity.

The scope activity defines fault handlers for a collection of activities, where each activity is nested within a catch clause, and if a fault occurs, a fault handler for the activity handles the fault. The fault handler uses compensation handlers to undo actions that have already been committed. The scope activity ensures that either all activities defined within the scope will complete successfully, or all activities are "compensated."

To enable compensation handlers, partners need to provide an undo operation for every "do" operation. For example, if there is an operation that allows "BuyTicket" from a company called SafeAirlines, SafeAirlines must also provide a "CancelTicket" operation.

Activity

A BPEL4WS process uses activities to choreograph Web services into longer running e-business dialogues. BPEL4WS provides a collection of basic and structured activities to use in a process. The difference between the two types of activities is that a basic activity cannot enclose other activities while a structured activity encloses a collection of activities. The basic activities are: empty, invoke, receive, reply, assign, wait, throw, and terminate. Structured activities are: flow, switch, while, sequence, pick, and scope.

A BPEL4WS process interacts with other Web services using invoke, receive and reply activities. A BPEL4WS process only allows one activity per process, so if you need to conduct a collection of activities, you can use a structured activity to enclose the collection.

Table 1 provides a summary of the BPEL4WS Process components.


Table 1. BPEL4WS Process components
Table 1: Choreography makes Web services dance

Building reliable asynchronous processes

To enable a realistic public process between two business partners, it is necessary to create it as an asynchronous process, which is the key to flexible and longer running e-business dialogues. Recall that BPEL4WS processes are layered over Web services, adding business process to the basic functionality provided by Web services. BPEL4WS processes introduce state-full interactions, co-relate independent Web services, define partners, activities, data containers, condition statements, and many other features to provide flexible and more descriptive e-business dialogues.

Web services perform synchronous operations by default. This means that a service requester sends a request and waits until a response is received from the service provider. But what happens if the connection is lost? What if it takes longer to furnish a response? While Company A is waiting, how will it know if Company B is busy working on its requests, or that Company B never received the request? This method of communication has two problems: it is synchronous and unreliable.

The "business transactions" are typically longer running activities that might take hours to respond, and in these transactions, both parties need to be sure that the messages are being received. A simple way to enable reliable messaging is for each party to send back a simple "signal" acknowledging receipt of the message. In this mode, even if Company B takes 2 hours to reply to a Purchase Order (PO) Request, it will acknowledge the receipt of the PO Request immediately. This way Company A knows that the request order has been received; otherwise Company A might start sending the same PO request repeatedly, causing confusion, and hindering the e-business dialogue.

In a synchronous setup, only Company B, the service provider would implement a Web service. Company A would simply send a message and get the PO Response. To enable asynchronous communication using Web services, Company B needs to implement a Web service but so does Company A. This makes Company A and Company B peers in the process -- both parties can initiate conversation when necessary.

In the asynchronous setup, when Company A sends a purchase order request, it only receives a receipt acknowledging that request. Next, Company B invokes a Web service on Company A and sends the purchase order confirmation as a request, and receives a receipt acknowledging the purchase order confirmation as the response. For this article series, I have extended this simple idea into BPEL4WS processes, to allow for state-full, asynchronous, reliable interactions between business partners.


Room to improve in WSDL

The discussion of building real world Web services would not be complete if I did not mention that WSDL is a young effort, with some inadequacies that need to be addressed in a "version 2" release. The encouraging news is that the W3C has started several groups to look at various aspects of Web services including the Web Services Architecture Group, the Web services Description Group, and more recently, the WS Choreography group. These groups include veterans from EDI, RosettaNet, and ebXML that will hopefully keep the groups from re-inventing the wheel, and leverage solutions from the more mature standards.

If we look strictly at the WSDL side, the Web services definition encourages a relationship that is more of a service provider serving an anonymous service requester. A WSDL file simply tells a client how to access the services; it has no provisions for the service provider to find out about the service requester. Real e-business dialogue requires a more peer-to-peer role, meaning that both partners can be providers and requesters. In WSDL, the service provider cannot initiate the dialogue; it has to wait for a request and can only send a response. This setup makes it difficult to establish colleague-to-colleague relationships, and awkward to construct dialogues that require asynchronous operations.

BPEL4WS is a very recent effort and will take time to mature. One of the problems of working with BPEL4WS is using an even younger alpha version BPWS4J engine. The BPWS4J engine does not implement the entire BPEL4WS spec and that has caused a few problems. The most significant problem is that at the time of this writing, the BPWS4J only allows RPC calls. Sending the document as an RPC call causes problems when you have to pass larger documents to your BPEL4WS process, as it is a very tedious process.

However, keep in mind that BPWS4J is a research vehicle in alpha stages, and not intended for actual production deployment.


Building the e-business dialogue

You need a variety of languages and tools to build and execute the e-business dialogue. Her, I am using the definition of an e-business dialogue, the choreography and messages definitions, from RosettaNet. The e-business dialogue is written using a mix of WSDL and BPEL4WS, which are both XML-based languages, and the internal Web services interact with applications written in Java programming language.


Figure 2. The e-business dialogue
Figure 2. The e-business dialogue

Building the public Web service definitions

I'll start by building the WSDL definitions for the two public and one private Web service, starting with the poRequester.wsdl Web service (second component in Figure 2) to be deployed on ACME. This Web service allows the Inventory Manager to replenish inventory by placing a purchase order for the needed inventory. For more details on working with WSDL, please refer to the resources.

BPEL4WS enabled WSDL definitions require some additional information and since this WSDL file will be used in the BPEL4WS process, it requires a service link definition to be added to the file. Service links enable partners in the BPEL4WS process to be linked to actual "actions" defined in the Web service. Another deviation from the normal WSDL definition is that you also don't have to describe the binding section for the WSDL definition, the bpws4j automatically generates the bindings necessary to interact with the defined port types.

Let us now look at the poRequester.wsdl file (see Listing 1).


Listing 1. poRequester.wsdl
<!-- Author: Suhayl Masud. SuhaylA@DifferentThinking.com    http://www.DifferentThinking.com -->

<definitions targetNamespace="http://www.acme.com/services/poRequester"
             xmlns:ACME="http://www.acme.com/services/poRequester"
	      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:slt="http://schemas.xmlsoap.org/ws/2002/07/service-link/"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns="http://schemas.xmlsoap.org/wsdl/">

   <message name="ReplenishRequestType">
      <part name="PORequest" type="xsd:string"/>
   </message>
   <message name="ReceiptAckType">
      <part name="receiptAck" type="xsd:string"/>
   </message>

   <portType name="replenishRequestPort">
      <operation name="replenishRequest">
         <input message="ACME:ReplenishRequestType"/>
         <output message="ACME:ReceiptAckType"/>
      </operation>
   </portType>

   <slt:serviceLinkType name="replenishRequestSLT">
     <slt:role name="inventoryService">
       <slt:portType name="ACME:replenishRequestPort"/>
     </slt:role>
   </slt:serviceLinkType>

   <!-- Note: This process will be installed on BPEL Engine, it will generate-->
   <!-- The bindings information automatically -->
   <service name="ACMEPORequesterServiceBP">
   </service>
</definitions>

There are two messages in this Web service, a request for purchase order, and a message that acknowledges the receipt of the request. In the complete scenario, the replenish PO message is a complete RosettaNet purchase order, and the receipt message is also more elaborate and contains a copy of the message it is acknowledging. These features will be added in the next article, for now we will keep both messages simple.

The BPEL4WS process defines capabilities of partners by using service links that link a partner to a Port Type and a set of operations in the WSDL file, as you can see in Listing 1. In a typical WSDL definition the next section is for defining the binding information that specifies the format of the messages sent to the Web service, and the address to send the messages to. However, since we are deploying this Web service as an associated component of a BPEL4WS process, the BPWS4J engine generates the necessary bindings so the BPEL4WS process can absorb the Web service, listening to the defined ports for any activity. Therefore, you will see in Listing 11 that the bindings and service sections of the WSDL definition are empty.

The public Web service on JoeLaptops, LaptopsIncPlacePO.wsdl (fourth component in Figure 2) takes a Purchase Order Request as input and sends a Receipt Acknowledgement as a response, in a structure similar to the Web service we just defined (see Listing 2).


Listing 2. LaptopsIncPlacePO.wsdl
<!-- Author: Suhayl Masud. SuhaylA@DifferentThinking.com http://www.DifferentThinking.com -->

<definitions targetNamespace="http://www.laptops.com/wsdl/POService"
             xmlns:LPTS="http://www.laptops.com/wsdl/POService"
             xmlns:LPTS2="http://www.laptops.com/wsdl/SalesService"
             xmlns:LPTS3="http://www.laptops.com/wsdl/ShippingService"
             xmlns:slt="http://schemas.xmlsoap.org/ws/2002/07/service-link/"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns="http://schemas.xmlsoap.org/wsdl/">
   <message name="PORequestType">
      <part name="PORequest" type="xsd:string"/>
   </message>
   <message name="ReceiptAckPORequestType">
      <part name="receipt" type="xsd:string"/>
   </message>

   <portType name="placePORequestPort">
      <operation name="placePORequest">
         <input message="LPTS:PORequestType"/>
         <output message="LPTS:ReceiptAckPORequestType"/>
      </operation>
   </portType>

   <slt:serviceLinkType name="PORequestSLT">
     <slt:role name="buyer">
       <slt:portType name="LPTS:placePORequestPort"/>
     </slt:role>
   </slt:serviceLinkType>

   <slt:serviceLinkType name="InternalPORequestSLT">
     <slt:role name="internalSales">
       <slt:portType name="LPTS2:SalesServicePT"/>
     </slt:role>
   </slt:serviceLinkType>

   <slt:serviceLinkType name="InternalPOShippingSLT">
     <slt:role name="internalShipping">
       <slt:portType name="LPTS3:ShippingServicePT"/>
     </slt:role>
   </slt:serviceLinkType>

   <!-- Note: This process will be installed on BPEL Engine, it will generate-->
   <!-- The bindings information automatically -->
   <service name="placePORequestServiceBP">
   </service>
</definitions>

Referring to the public process in Figure 2, you can see that ACME sends a purchase order request to JoeLaptops and receives a receipt message. Next, JoeLaptops sends ACME a substantive Purchase Order Acceptance response. To enable ACME to receive this PO Acceptance message, I will next define the poAcceptanceReceiver.wsdl Web service on ACME (component six in Figure 2). Its purpose is to receive a PO Acceptance and to send a response acknowledging receipt of the PO Acceptance. The definition is straightforward and follows the same logic as the previous two definitions (see Listing 3).


Listing 3. poAcceptanceReceiver.wsdl
<!-- Author: Suhayl Masud. SuhayAl@DifferentThinking.com http://www.DifferentThinking.com -->

<definitions targetNamespace="http://www.acme.com/services/poAcceptanceReceiver"
             xmlns:ac="http://www.acme.com/services/poAcceptanceReceiver"
             xmlns:acl="http://www.acme.com/services/acmeAccountsService"	       
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:slt="http://schemas.xmlsoap.org/ws/2002/07/service-link/"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns="http://schemas.xmlsoap.org/wsdl/">

   <message name="POAcceptanceType">
      <part name="POAcceptance" type="xsd:string"/>
   </message>
   <message name="ReceiptAckType">
      <part name="receiptAck" type="xsd:string"/>
   </message>

   <portType name="sendPOAcceptancePort">
      <operation name="sendPOAcceptance">
         <input message="ac:POAcceptanceType"/>
         <output message="ac:ReceiptAckType"/>
      </operation>
   </portType>

   <slt:serviceLinkType name="POAcceptanceSLT">
      <slt:role name="POService">
        <slt:portType name="ac:sendPOAcceptancePort"/>
      </slt:role>
   </slt:serviceLinkType>
   <slt:serviceLinkType name="AccountsServiceSLT">
      <slt:role name="service">
        <slt:portType name="acl:AccountsServicePT"/>
      </slt:role>
   </slt:serviceLinkType>

   <!-- Note: This process will be installed on BPEL Engine, it will generate-->
   <!-- The bindings information automatically -->
   <service name="ACMEPOReceiverServiceBP">
   </service>
</definitions>

Now that you have defined the WSDL definitions, the next step is to create the BPEL4WS processes that will use these Web service definitions to conduct business processes.

Building the BPEL4WS processes

Conceptually, you need to build only two BPEL4WS processes, one for ACME and another for JoeLaptops. However, due to a minor bug in the early alpha version of the BPWS4J engine, you will need to split the process on ACME as two separate BPEL4WS processes.


Figure 3. Using the BPWS4J editor in Eclipse to create ACMEPORequester.BPEL
Figure 3. Using the BPWS4J editor in Eclipse to create ACMEPORequester.BPEL

The first BPEL4WS process on ACME is ACMEPORequester.BPEL (component one in Figure 2). It is layered on top of the poRequester.wsdl we created earlier (see also Figure 3). This process takes a PO request from an Inventory Manager, and then sends that request to JoeLaptops by invoking the placePORequest operation on the Web service hosted by JoeLaptops. The process passes the result of this invocation, just a receipt acknowledgment for your simple scenario, back to the Inventory Manager.

The second BPEL4WS process on ACME is ACMEPOReceiver.BPEL (component thirteen in Figure 2), layered on top of poAcceptanceReceiver.wsdl. This process receives the PO acceptance message sent by JoeLaptops, and sends back a receipt message to JoeLaptops.

JoeLaptops hosts the third BPEL4WS process (component five in Figure 2). It receives a PO request from the ACMEPORequester process and sends a receipt message to the requester, and then it sends the requester (ACMEPOReceiver process) a PO Acceptance message, and receives a receipt message.

During the construction and testing phase of the BPEL4WS processes, it is important to examine the log files on both BPWS4J engines (two engines simulating the ACME and JoeLaptops environments), to gain insight on how the processes are working. To continue your definitions, you will next define the ACMEPORequester.BPEL (see Listing 4).


Listing 4. ACMEPORequester.bpel
<!-- Author: Suhayl Masud. Suhayl@DifferentThinking.com http://www.DifferentThinking.com -->

<process name="acmePORequesterProcess"
          targetNamespace="http://www.acme.com/services/acmePORequesterProcess"
          xmlns="http://schemas.xmlsoap.org/ws/2002/07/business-process/"
          xmlns:acmePOR="http://www.acme.com/services/poRequester"
          xmlns:laptopsPO="http://www.laptops.com/wsdl/POService">

<!-- This process has two partners, the internal ACME inventory service that triggers the -->
<!-- process and the POFulfiller (Laptops Inc), to whom the PORequest is sent             -->

  <partners>
    <partner name="inventoryService" serviceLinkType="acmePOR:replenishRequestSLT"/>
    <partner name="POFulfiller" serviceLinkType="laptopsPO:PORequestSLT"/>
  </partners>

  <containers>
    <container name="replenishRequestCTR" messageType="acmePOR:ReplenishRequestType"/>
    <container name="replenishResponseCTR" messageType="acmePOR:ReceiptAckType"/>
    <container name="outputPORequestAckContainer" 
    messageType="laptopsPO:ReceiptAckPORequestType"/>
  </containers>

<sequence name="placePOSequence">

<!-- Receive the inventory manager PO Request and store it in replenishRequest container-->

   <receive name="ReplenishRecieve"
             partner="inventoryService" portType="acmePOR:replenishRequestPort" 
             operation="replenishRequest"
             container="replenishRequestCTR" createInstance="yes">
   </receive>   


<!-- Initialize container -->
<assign>
      <copy>
     	  <from expression="'initializing'"/>
        <to container="replenishResponseCTR" part="receiptAck"/>
      </copy>
</assign>
 
<!-- Invoke placePORequest service at Laptops Inc -->
<invoke name="PlacePOwithSeller"
            partner="POFulfiller" portType="laptopsPO:placePORequest" operation="placePORequest"
            inputContainer="replenishRequestCTR" 
            outputContainer="outputPORequestAckContainer"/>

<!-- Copy Receipt Ack from Laptops Inc to be sent to Inventory Manager -->
<assign>
      <copy>
         <from container="outputPORequestAckContainer" part="receipt"/>
         <to container="replenishResponseCTR" part="receiptAck"/>
      </copy>
</assign>

<!-- Reply to inventory manager with the receipt ack of the PO Order sent by laptops Inc -->
<reply name="ReplenishResponse"
           partner="inventoryService" portType="acmePOR:replenishRequestPort" 
           operation="replenishRequest"
           container="replenishResponseCTR">
</reply>
</sequence>
</process>

There are two partners in this process. the first partner is the Inventory Manager, defined as the inventory Service in the definition below. The Inventory Manager interacts with the process through operations defined in the "replenishRequestSLT" service link. The second partner plays the role of a PO fulfiller in this process, the partner definition describes that the process can interact with JoeLaptops through the "PORequestSLT" service link defined in the JoeLaptops WSDL file:

 
  <partners>
    <partner name="inventoryService" serviceLinkType="acmePOR:replenishRequestSLT"/>
    <partner name="POFulfiller" serviceLinkType="laptopsPO:PORequestSLT"/>
  </partners>

Next, you will build the containers required to contain the data the process is receiving and sending. There are four containers in this process, the first two are used to receive from and respond to the Inventory Manager. The next two containers are used in interaction with JoeLaptops, they are sent as part of an invoke request, with an input container containing the message being sent to JoeLaptops, and the output container containing the message sent from JoeLaptops:

 
  <containers>
    <container name="replenishRequest" messageType="acmePOR:ReplenishRequestType"/>
    <container name="replenishResponse" messageType="acmePOR:ReceiptAckType"/>
    <container name="inputPORequestContainer" messageType="laptopsPO:PORequestType"/>
    <container name="outputPORequestAckContainer" 
    messageType="laptopsPO:ReceiptAckPORequestType"/>
  </containers>

Having defined the partners and containers of the process, you will now define the activity of the process. You will use a simple sequence activity to coordinate the process. It performs the following tasks:

Begin sequence

  • Receive a PO request from the Inventory Manager.
  • Assign the data from the request container to the container to be sent to JoeLaptops.
  • Invoke a "place purchase order" request with JoeLaptops.
  • Assign the information from JoeLaptops to container being sent to Inventory Manager.
  • Reply to the Inventory Manager with the response from JoeLaptops.
End sequence

Here is how the sequence is defined:

<sequence name="placePOSequence">
  <receive name="ReplenishRecieve"
            partner="inventoryService" portType="acmePOR:replenishRequestPort" 
            operation="replenishRequest"
            container="replenishRequest" createInstance="yes">
  </receive>

The receive activity defines the type of partners that can interact with the process and what operations they can use. The incoming request message is stored in the replenishRequest container. The next activity of interest is the invoke activity:

  <invoke name="PlacePOwithSeller"
         partner="POFulfiller" portType="laptopsPO:placePORequest" operation="placePORequest"
         inputContainer="inputPORequestContainer" outputContainer="outputPORequestAckContainer">
  </invoke>

This invoke activity requires two actions from the receiver, which is JoeLaptops in our case. In the definition above, the invoke activity interacts with the placePORequest operation of the JoeLaptops Web service defined in LaptopsIncPlacePO.wsdl. The input container of the invoke activity is treated as the input message of the operation and the output container will receive the output message from the placePORequest operation. The above definition will enable the acmePORequesterProcess to place a purchase order request with JoeLaptops, and receive the receipt acknowledgement message in the output container.

Next, we will define an assign activity that copies the information returned from JoeLaptops to the container that will be used to send information to the Inventory Manager:

<assign name="copyreceivedreceipt">
      <copy>
     	<from container="outputPORequestAckContainer" part="receipt"/>
      	<to container="replenishResponse" part="receiptAck"/>
      </copy>
</assign>   

In the simple scenario, the information sent back to the Inventory Manager is only a receipt acknowledgment message. In the complete scenario, the Inventory Manager will receive the PO Acceptance manager instead.

Now to wrap up the acmePORequesterProcess, we will define the reply activity, which is the response to the request that the Inventory Manager had sent in the beginning of the process. This is what the reply activity looks like:

<reply name="ReplenishResponse"
           partner="inventoryService" portType="acmePOR:replenishRequestPort" 
           operation="replenishRequest"
           container="replenishResponse">
</reply>
</sequence>
</process> 

The second BPEL4WS process at ACME is the ACMEPOReceiver.BPEL (see Listing 5) and it works like this:

Begin sequence

  • Receive the PO Acceptance from JoeLaptops.
  • Assign a receipt acknowledged message to the container sent in the reply activity.
  • Reply to JoeLaptops with the receipt acknowledgemen.t
End sequence


Listing 5. ACMEPOReceiver.bpel
<!-- Author: Suhayl Masud. SuhaylA@DifferentThinking.com http://www.DifferentThinking.com -->

<process name="acmePOReceiverProcess"
	   targetNamespace="http://www.acme.com/services/acmePOReceiverProcess"
	   xmlns="http://schemas.xmlsoap.org/ws/2002/07/business-process/"
         xmlns:acmePOA="http://www.acme.com/services/poAcceptanceReceiver"
	   xmlns:acmeAcct="http://www.acme.com/service/accountsService"
  	   xmlns:laptopsPO="http://www.laptops.com/services/LaptopsIncPlacePO">

<!-- The process has two partners. JoeLaptops, which is the acceptance notifier -->
<!-- and sends the process the PO confirmation, and the second partner is an internal -->
<!-- Accounts service that is informed of the latest purchase that needs to be paid -->

  <partners>
     <partner name="POAcceptanceNotifier" serviceLinkType="acmePOA:POAcceptanceSLT"/>
     <partner name="Accounting" serviceLinkType="acmeAcct:AccountsServiceSLT"/>
  </partners>

<containers>
    <container name="POAcceptanceContainer" messageType="acmePOA:POAcceptanceType"/>
    <container name="POAcceptanceReceipt" messageType="acmePOA:ReceiptAckType"/>
    <container name="PurchaseReport" messageType="acmeAcct:reportPurchaseMsg"/>
</containers>

<sequence name="receivePOSequence">

<!-- The process receives the PO confirmation from JoeLaptops -->
<receive name="ReceivePOAcceptance"
             partner="POAcceptanceNotifier" portType="acmePOA:sendPOAcceptancePort" 
             operation="sendPOAcceptance"
             container="POAcceptanceContainer" createInstance="yes">
</receive>   

<!-- Copy acknowledgement of the PO Confirmation to be sent to JoeLaptops -->
<assign>
      <copy>
        <from expression="'Acme corp has received your PO Acceptance. Thank you'"/>
        <to container="POAcceptanceReceipt" part="receiptAck"/>
      </copy>
</assign>

<!-- Send JoeLaptops Receipt Acknowledging the PO Confirmation -->
<reply name="POAcceptanceReceiptAck"
           partner="POAcceptanceNotifier" portType="acmePOA:sendPOAcceptancePort" 
           operation="sendPOAcceptance"
           container="POAcceptanceReceipt">
</reply>

<!-- Copy the POConfirmation to a purchase report container -->
<assign>
      <copy>
        <from container="POAcceptanceContainer" part="POAcceptance"/>
        <to container="PurchaseReport" part="purchaseReport"/>
      </copy>
</assign>

<!-- Send the accounting service the purchase report -->

<invoke name="invoke" partner="Accounting" portType="acmeAcct:AccountsServicePT"
            operation="reportPurchase" inputContainer="PurchaseReport" 
            outputContainer="POAcceptanceReceipt"/>
</sequence>
</process>

Finally, here is what the LaptopPlacePOProcess does (see component five in Figure 2), and how it is defined:

Begin sequence

  • Receive the PO Request from ACMEPORequester process.
  • Assign a receipt message in the container used in the reply activity.
  • Reply to ACMEPORequester process.
  • Assign an acceptance message in the input container used in the invoke activity.
  • Invoke the ACMEPOReceiver process and send the PO Acceptance message.
End sequence

The acceptance message in this simple scenario is a simple string. In the complete scenario, it will be a purchase order acceptance message (see Listing 6).


Listing 6. ACMEPOReceiver.bpel
<!-- Author: Suhayl Masud. SuhaylA@DifferentThinking.com  http://www.DifferentThinking.com -->

<process xmlns="http://schemas.xmlsoap.org/ws/2002/07/business-process/"
         name="laptopsPlacePOProcess"
         targetNamespace="http://www.laptops.com/services/POService"
         xmlns:tns="http://www.laptops.com/wsdl/POService"
	   xmlns:tns2="http://localhost:8080/laptops/laptopsSalesService.wsdl"
 	   xmlns:tns3="http://localhost:8080/laptops/laptopsShippingService.wsdl"
	   xmlns:acme="http://localhost:8080/acme/ACMEPOAcceptance.wsdl">

<!-- Define Partners -->
  <partners>
    <partner name="buyer" serviceLinkType="tns:PORequestSLT"/>
    <partner name="internalSales" serviceLinkType="tns:InternalPORequestSLT"/>
    <partner name="internalShipping" serviceLinkType="tns:InternalPOShippingSLT"/>
    <partner name="acceptanceReceiver" serviceLinkType="acme:PORequestSLT"/>
  </partners>

<!-- Define Containers used when interacting with partners -->
  <containers>
    <container name="PORequestCtr" messageType="tns:PORequestType"/>
    <container name="internalPORequest" messageType="tns2:fillPORequest"/>
    <container name="internalPOAcceptance" messageType="tns2:poConfirmation"/>
    <container name="internalShippingOrder" messageType="tns3:shipPurchaseOrder"/>    
    <container name="internalSOResp" messageType="tns3:shipPOResp"/>        
    <container name="POAcceptance" messageType="acme:POAcceptanceType"/>
    <container name="buyerReceipt" messageType="acme:ReceiptAckType"/>
    <container name="LaptopsReceiptAck" messageType="tns:ReceiptAckPORequestType"/>
  </containers>

  <sequence name="placePOSequence">
  
<!-- Receive PORequest from ACME -->
  
    <receive name="RecievePORequest"
              partner="buyer" portType="tns:placePORequestPort" operation="placePORequest"
             container="PORequestCtr" createInstance="yes">
    </receive>

<!-- initialize Containers -->
    <assign>
      <copy>
        <from expression="'initializing'"/>
        <to container="internalPORequest" part="poRequest"/>
      </copy>
    </assign>
    <assign>
      <copy>
        <from expression="'Receipt Acknowledgement This message is to acknowledge 
        that Laptops Inc have received your PO Request. We are working on the 
        response which you will receive shortly'"/>
        <to container="LaptopsReceiptAck" part="receipt"/>
      </copy>
    </assign>

<!-- initialize internalShippingOrder -->	
    <assign>
      <copy>
        <from expression="'initializing'"/>
        <to container="internalShippingOrder" part="shipPOAcceptance"/>
      </copy>	
    </assign>
    <assign>
      <copy>
        <from expression="'initializing'"/>
        <to container="internalShippingOrder" part="poShippingOrder"/>
      </copy>	
    </assign>

<!-- initialize internalSOResponse -->	
    <assign>
      <copy>
        <from expression="'initializing'"/>
        <to container="internalSOResp" part="shipResponse"/>
      </copy>	
    </assign>

<!-- Send ACME Receipt Acknowledgment of PORequest -->
    <reply name="ReceiptAckActivity"
           partner="buyer" portType="tns:placePORequestPort" operation="placePORequest"
           container="LaptopsReceiptAck">
    </reply>

<!-- copy PORequest to container used for internal PORequest -->
    <assign>
      <copy>
        <from container="PORequestCtr" part="PORequest"/>
        <to container="internalPORequest" part="poRequest"/>
      </copy>
	</assign>

<!-- Ask Internal Sales department to process PORequest -->
<invoke name="invoke" partner="internalSales" portType="tns2:SalesServicePT"
            operation="fillPO" inputContainer="internalPORequest" 
            outputContainer="internalPOAcceptance"/>

<!-- Copy the response from Internal Sales to send to ACME -->
  <assign>
      <copy>
        <from container="internalPOAcceptance" part="poConfirmation"/>
        <to container="POAcceptance" part="POAcceptance"/>
      </copy>
  </assign>

<!-- Send ACME substantive message, letting ACME know if the PO was accepted -->
    <invoke name="SendBuyerPOAcceptance"
       partner="acceptanceReceiver" portType="acme:sendPOAcceptancePort" 
       operation="sendPOAcceptance"
       inputContainer="POAcceptance" outputContainer="buyerReceipt">
    </invoke>

<!-- Copy ACME's receipt message of the POConfirmation to container for 
internal shipping service -->
  <assign>
      <copy>
        <from container="buyerReceipt" part="receiptAck"/>
        <to container="internalShippingOrder" part="shipPOAcceptance"/>
      </copy>
  </assign>

<!-- Copy POConfirmation to container for internal shipping service -->
  <assign>
	<copy>
       <from container="internalPOAcceptance" part="poConfirmation"/>
       <to container="internalShippingOrder" part="poShippingOrder"/>
      </copy>
  </assign>

<!-- Send POConfirmation and ACME's receipt acknowledging the POConfirmation to 
the shipping service -->

  <invoke name="invokeShipping" partner="internalShipping" portType="tns3:ShippingServicePT"
   operation="shipPO" inputContainer="internalShippingOrder" outputContainer="internalSOResp"/>
</sequence>
</process>
 

Are we there yet? Almost. You have to construct the remaining six components described in Figure 2, to enable BPEL4WS processes to interact with internal applications and Web services. You also need to start exchanging real RosettaNet-based purchase order data. In the next article, I will expand the simple scenario created here into a robust e-business dialogue.



Download

NameSizeDownload method
ws-rose4.zip HTTP

Information about download methods


Resources

About the author

Suhayl Masud is the president of Different Thinking, a consulting firm that enables organizations to understand and conduct electronic business, by providing training, architecture, and application construction services. Suhayl is also the co-founder of Agile Webservices, providing Policy Based Computing solutions. Suhayl's experience includes consulting as the lead technical architect for RosettaNet, where he helped define the next generation of e-business process standards. Suhayl would love to hear from you at: SuhaylA@DifferentThinking.com

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and Web services
ArticleID=11843
ArticleTitle=Use RosettaNet-based Web services, Part 4: BPEL4WS and RosettaNet
publish-date=09302003
author1-email=SuhaylA@DifferentThinking.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers