Business Processes with BPEL

Exclusive offer: get 50% off this eBook here
WS-BPEL 2.0 for SOA Composite Applications with Oracle SOA Suite 11g

WS-BPEL 2.0 for SOA Composite Applications with Oracle SOA Suite 11g — Save 50%

Define, model, implement, and monitor real-world BPEL business processes with SOA powered BPM for Oracle SOA Suite with this book and eBook

$41.99    $21.00
by Marcel Krizevnik Matjaz B. Juric | September 2010 | BPEL Enterprise Articles SOA Oracle

In this article, by Matjaz B. Juric & Marcel Krizevnik, authors of WS-BPEL 2.0 for SOA Composite Applications with Oracle SOA Suite 11g, we will demonstrate how business processes are described with BPEL and define a simple business process for business travels.

We will specifically cover the following topics:

  • BPEL business process example
  • Involved services
  • Employee Travel Status service
  • Airline service
  • WSDL for the BPEL process
  • Partner link types
  • Business process definition
  • BPEL process outline
  • Partner links
  • Variables for the Travel Process
  • BPEL process main body
  • Asynchronous BPEL example
  • Modify the BPEL Process WSDL
  • Modify partner link types
  • Modify the BPEL process definition

(For more resources on BPEL, SOA and Oracle see here.)

BPEL business process example

We describe an oversimplified scenario, where the client invokes the business process, specifying the name of the employee, the destination, the departure date, and the return date. The BPEL business process first checks the employee travel status. We will assume that a service exists through which such a check can be made. Then the BPEL process will check the price for the flight ticket with two airlines—American Airlines and Delta Airlines. Again we will suppose that both airline companies provide a service through which such checks can be made. Finally, the BPEL process will select the lower price and return the travel plan to the client.

For the purpose of this example, we first build a synchronous BPEL process, to maintain simplicity. This means that the client will wait for the response. Later in this article, we modify the example and make the BPEL process asynchronous. We will assume that the service for checking the employee travel status is synchronous. This is reasonable because such data can be obtained immediately and returned to the caller.

To acquire the plane ticket prices we use asynchronous invocations. Again, this is reasonable because it might take a little longer to confirm the plane travel schedule. We assume that both airlines offer a service and that both Web Services are identical(provide equal port types and operations). This assumption simplifies our example. In real-world scenarios, you will usually not have the choice about the services but will have to use whatever services are provided by your partners. If you have the luxury of designing the Web Services along with the BPEL process, consider which is the best interface. Usually we use asynchronous services for long-lasting operations and synchronous services for operations that return a result in a relatively short time. If we use asynchronous services, the BPEL process is usually asynchronous as well. In our example, we first develop a synchronous BPEL process that invokes two asynchronous airline Web Services. This is legal, but not recommended in real-world scenarios since the client may have to wait for an arbitrarily long time. In the real world, the solution would be to develop an asynchronous BPEL process, which we will cover later in this article.

We invoke Web Services of both airlines concurrently and asynchronously. This means that our BPEL process will have to implement the callback operation (and a port type), through which the airlines will return the flight ticket confirmation.

Finally, the BPEL process returns the best airline ticket to the client. In this example, to maintain simplicity, we will not implement any fault handling, which is crucial in real-world scenarios.

Let's start by presenting the BPEL process activities using a UML activity diagram. In each activity, we have used the stereotype to indicate the BPEL operation used.

Although the presented process might seem very simple, it will offer a good start for learning BPEL. To develop the BPEL process, we will go through the following steps:

  • Get familiar with the involved services
  • Define the WSDL for the BPEL process
  • Define partner link types
  • Define partner links
  • Declare variables
  • Write the process logic definition

Involved services

Before we can start writing the BPEL process definition, we have to get familiar with all services invoked from our business process. These services are sometimes called partner services. In our example, three services are involved:

  • The Employee Travel Status service
  • The American Airlines service
  • The Delta Airlines service

The two airline services share equal WSDL descriptions.

The services used in this example are not real, so we will have to write WSDLs and even implement them to run the example. In real-world scenarios we would obviously use real Web Services exposed by partners involved in the business process.

The services and the BPEL process example can be downloaded from http://www.packtpub.com The example runs on the Oracle SOA Suite.

Web Service descriptions are available through WSDL. WSDL specifies the operations and port types Web Services offer, the messages they accept, and the types they define. We will now look at both Web Services.

Employee Travel Status service

Understanding the services that a business process interacts with is crucial to writing the BPEL process definition. Let's look into the details of our Employee Travel Status service. It provides the EmployeeTravelStatusPT port type through which the employee travel status can be checked using the EmployeeTravelStatus operation. The operation will return the travel class an employee can use—economy, business, or first. This is shown in the following figure:

The operation is a synchronous request/response operation as we can see from the WSDL:

<?xml version="1.0" encoding="utf-8" ?>
<definitions
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc=
"http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://packtpub.com/service/employee/"
targetNamespace="http://packtpub.com/service/employee/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype">
...
<portType name="EmployeeTravelStatusPT">
<operation name="EmployeeTravelStatus">
<input message="tns:EmployeeTravelStatusRequestMessage" />
<output message="tns:EmployeeTravelStatusResponseMessage" />
</operation>
</portType>
...

The EmployeeTravelStatus operation consists of an input and an output message. To maintain simplicity, the fault is not declared. The definitions of input and output messages are also a part of the WSDL:

...
<message name="EmployeeTravelStatusRequestMessage">
<part name="employee" element="tns:Employee" />
</message>
<message name="EmployeeTravelStatusResponseMessage">
<part name="travelClass" element="tns:TravelClass" />
</message>
...

The EmployeeTravelStatusRequestMessage message has a single part—employee of element Employee with type EmployeeType, while the EmployeeTravelStatusResponseMessage has a part called travelClass, of element TravelClass and type TravelClassType. The EmployeeType and the TravelClassType types are defined within the WSDL under the &lttypes> element:

...
<types>
<xs:schema elementFormDefault="qualified"
targetNamespace="http://packtpub.com/service/employee/">

<xs:complexType name="EmployeeType">
<xs:sequence>
<xs:element name="FirstName" type="xs:string" />
<xs:element name="LastName" type="xs:string" />
<xs:element name="Department" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="Employee" type="EmployeeType"/>
...

EmployeeType is a complex type and has three elements: first name, last name, and department name. TravelClassType is a simple type that uses the enumeration to list the possible classes:

...
<xs:simpleType name="TravelClassType">
<xs:restriction base="xs:string">
<xs:enumeration value="Economy"/>
<xs:enumeration value="Business"/>
<xs:enumeration value="First"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="TravelClass" type="TravelClassType"/>
</xs:schema>
</types>
...

Now let us look at the airline service.

Airline service

The Airline Service is an asynchronous web service. Therefore, it specifies two port types. The first, FlightAvailabilityPT, is used to check the flight availability using the FlightAvailability operation. To return the result, the service specifies the second port type, FlightCallbackPT. This port type specifies the FlightTicketCallback operation.

Although the Airline Service defines two port types, it only implements the FlightAvailabilityPT. FlightCallbackPT is implemented by the BPEL process, which is the client of the web service. The architecture of the service is schematically shown as follows:

Flight Availability port type

FlightAvailability is an asynchronous operation, containing only the input message.

<?xml version="1.0" encoding="utf-8" ?>
<definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:emp="http://packtpub.com/service/employee/"
xmlns:tns="http://packtpub.com/service/airline/"
targetNamespace="http://packtpub.com/service/airline/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype">
...
<portType name="FlightAvailabilityPT">
<operation name="FlightAvailability">
<input message="tns:FlightTicketRequestMessage" />
</operation>
</portType>
...

The definition of the input message is shown as follows. It consists of two parts—the flightData part and the travelClass part:

<message name="FlightTicketRequestMessage">
<part name="flightData" element="tns:FlightRequest" />
<part name="travelClass" element="emp:TravelClass" />
</message>

The travelClass part is the same as that used in the Employee Travel Status service. The flightData part is of element FlightRequest, which is defined as follows:

...
<types>
<xs:schema elementFormDefault="qualified"
targetNamespace="http://packtpub.com/service/airline/">

<xs:complexType name="FlightRequestType">
<xs:sequence>
<xs:element name="OriginFrom" type="xs:string" />
<xs:element name="DestinationTo" type="xs:string" />
<xs:element name="DesiredDepartureDate" type="xs:date" />
<xs:element name="DesiredReturnDate" type="xs:date" />
</xs:sequence>
</xs:complexType>
<xs:element name="FlightRequest" type="FlightRequestType"/>
...

FlightRequestType is a complex type and has four elements through which we specify the flight origin and destination, the desired departure data, and the desired return date.

Flight Callback port type

The Airline Service needs to specify another port type for the callback operation through which the BPEL process receives the flight ticket response messages.

The service will only specify this port type, which is implemented by the BPEL process.

We define the FlightCallbackPT port type with the FlightTicketCallback operation, which has the TravelResponseMessage input message:

...
<portType name="FlightCallbackPT">
<operation name="FlightTicketCallback">
<input message="tns:TravelResponseMessage" />
</operation>
</portType>
...

TravelResponseMessage consists of a single part called confirmationData:

...
<message name="TravelResponseMessage">
<part name="confirmationData" element="tns:FlightConfirmation" />
</message>
...

Now that we are familiar with both services, we can define the BPEL process. Remember that our BPEL process is an actual web service. Therefore, we first have to write the WSDL for the BPEL process.

<xs:complexType name="FlightConfirmationType">
<xs:sequence>
<xs:element name="FlightNo" type="xs:string" />
<xs:element name="TravelClass" type="tns:TravelClassType" />
<xs:element name="Price" type="xs:float" />
<xs:element name="DepartureDateTime" type="xs:dateTime" />
<xs:element name="ReturnDateTime" type="xs:dateTime" />
<xs:element name="Approved" type="xs:boolean" />
</xs:sequence>
</xs:complexType>
<xs:element name="FlightConfirmation"
type="FlightConfirmationType"/>
</xs:schema>
</types>

WSDL for the BPEL process

The business travel BPEL process is exposed as a service. We need to define the WSDL for it. The process will have to receive messages from its clients and return results. So it has to expose a port type that will be used by the client to start the process and get the reply. We define the TravelApprovalPT port type with the TravelApproval operation, as shown in the following figure:

We have already said that the BPEL process is synchronous. The TravelApproval operation will be of synchronous request/response type.

<?xml version="1.0" encoding="utf-8" ?>
<definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:emp="http://packtpub.com/service/employee/"
xmlns:aln="http://packtpub.com/service/airline/"
xmlns:tns="http://packtpub.com/bpel/travel/"
targetNamespace="http://packtpub.com/bpel/travel/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype">
...
<portType name="TravelApprovalPT">
<operation name="TravelApproval">
<input message="tns:TravelRequestMessage" />
<output message="aln:TravelResponseMessage" />
</operation>
</portType>
...

We also have to define messages. The TravelRequestMessage consists of two parts:

  • employee: The employee data, which we reuse from the Employee Travel Status service definition
  • flightData: The flight data, which we reuse from the airline service definition

...
<import namespace="http://packtpub.com/service/employee/"
location="./Employee.wsdl"/>
<import namespace="http://packtpub.com/service/airline/"
location="./Airline.wsdl"/>
...
<message name="TravelRequestMessage">
<part name="employee" element="emp:Employee" />
<part name="flightData" element="aln:FlightRequest" />
</message>
...

For the output message, we use the same message used to return the flight information from the airline service: the TravelResponseMessage defined in the aln namespace. This is reasonable because the BPEL process will get the TravelResponseMessage from both airlines, select the most appropriate (the cheapest), and return the same message to the client. As we have already imported the Airline WSDL, we are done.

When writing the WSDL for the BPEL process, we usually do not define the binding (&ltbinding>) and the service (&ltservice>) sections. These are usually generated by the BPEL execution environment (BPEL server).

Before we can start writing the BPEL process, we still need to define partner link types.

WS-BPEL 2.0 for SOA Composite Applications with Oracle SOA Suite 11g Define, model, implement, and monitor real-world BPEL business processes with SOA powered BPM for Oracle SOA Suite with this book and eBook
Published: September 2010
eBook Price: $41.99
Book Price: $69.99
See more
Select your format and quantity:

Read more about this book

(For more resources on BPEL, SOA and Oracle see here.)

Partner link types

Partner link types represent the interaction between a BPEL process and the involved parties, which includes the services the BPEL process invokes and the client that invokes the BPEL process.

In our example, there are three different partners—the client, the employee travel status service, and the airline service. Ideally, each service should define the corresponding partner link types (in the WSDL). In real-world scenarios, this may not be the case. Then we can wrap the partner web service with a WSDL that imports the WSDL of the service and defines the partner link types. We define three partner link types, each in the corresponding WSDL of the service:

  • travelLT: This is used to describe the interaction between the BPEL process client and the BPEL process itself. This interaction is synchronous. This partner link type is defined in the WSDL of the BPEL process.
  • employeeLT: This is used to describe the interaction between the BPEL process and the Employee Travel Status service. This interaction is synchronous too. This partner link type is defined in the WSDL of the Employee service.
  • flightLT: This describes the interaction between the BPEL process and the Airline Service. This interaction is asynchronous and the Airline Service invokes a callback on the BPEL process. This partner link type is defined in the WSDL of the Airline Service.

We already know that each partner link type can have one or two roles and for each role we must specify the portType it uses. For synchronous operations, there is a single role for each partner link type because the operation is only invoked in a single direction.

For example, the client invokes the TravelApproval operation on the BPEL process. Because it is a synchronous operation, the client waits for completion and gets a response only after the operation is completed.

Note that if TravelApproval were an asynchronous callback operation, we would have to specify two roles. The first role would describe the invocation of the TravelApproval operation by the client. The second role would describe the invocation of a callback operation. This callback operation would be invoked by the BPEL process and would call the client to return the result. We will make our example process asynchronous later in this article. Remember that there is an asynchronous relationship between the BPEL process and the Airline Service.

As we have already figured out, we need three partner link types. In the first two we have to specify a single role because they deal with synchronous operations. In the third we need to specify both the roles because it is asynchronous.

Partner link types are defined within a special namespace (http://docs. oasis-open.org/wsbpel/2.0/plnktype). The reference to this namespace has to be included first as follows:

<definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:emp="http://packtpub.com/service/employee/"
xmlns:aln="http://packtpub.com/service/airline/"
xmlns:tns="http://packtpub.com/bpel/travel/"
targetNamespace="http://packtpub.com/bpel/travel/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype">
...

Now we can add the definitions for the partner link types. First, we define the travelLT link type in the BPEL process WSDL. This is used by clients to invoke the BPEL process. The only role required is the role of the travel service (our BPEL process). The client uses the TravelApprovalPT port type to communicate with the BPEL service:

...
<plnk:partnerLinkType name="travelLT">
<plnk:role name="travelService"
portType="tns:TravelApprovalPT" />
</plnk:partnerLinkType>
...

The second link type is employeeLT. It is used to describe the communication between the BPEL process and the Employee Travel Status service and is defined in the WSDL of the Employee service. The interaction is synchronous, so we need a single role, called employeeTravelStatusService. The BPEL process uses the EmployeeTravelStatusPT on the Employee service:

...
<plnk:partnerLinkType name="employeeLT">
<plnk:role name="employeeTravelStatusService"
portType="tns:EmployeeTravelStatusPT" />
</plnk:partnerLinkType>
...

The last partner link type is flightLT, used to describe the communication between the BPEL process and the Airline Service. This communication is asynchronous. The BPEL process invokes an asynchronous operation on the Airline Service. The web service, after it has completed the request, invokes a callback on the BPEL process. Therefore, we need two roles:

  • The first role describes the role of the Airline Service to the BPEL process, which is the airline service (airlineService). The BPEL process uses the FlightAvailabilityPT port type to make the asynchronous invocation.
  • The second role describes the role of the BPEL process to the Airline Services. For the Airline Service, the BPEL process is an airline customer, thus the role name is airlineCustomer. The Airline Service uses the FlightCallbackPT port type to make the callback.

This partner link type is defined in the WSDL of the Airline service:

...
<plnk:partnerLinkType name="flightLT">
<plnk:role name="airlineService"
portType="tns:FlightAvailabilityPT" />
<plnk:role name="airlineCustomer"
portType="tns:FlightCallbackPT" />
</plnk:partnerLinkType>
...

Understanding partner link types is crucial for developing a BPEL process specification. Sometimes it helps to make a diagram of all the interactions. Once the partner link types are defined, we have finished the preparation phase and are ready to start writing the business process definition.

Business process definition

The BPEL business process definition specifies the order of activities that have to be performed within a business process. Typically, a BPEL process waits for an incoming message, which starts the execution of the business process. This incoming message is usually the client request. Then a series of activities occur, either sequentially or in parallel. These activities include:

  • Invoking operations on other services
  • Receiving results from other services
  • Conditional branching, which influences the flow of the business process
  • Looping
  • Fault handling
  • Waiting for certain events to occur

In our example process, we do not cover all these aspects. We will leave loops, faults, and waits for the next chapter. Before we start defining our business process, let's have a quick look at the sequence diagram. It shows the messages exchanged between the involved parties.

The following parties are involved:

  • The client that will invoke the BPEL process
  • The BPEL process itself
  • The Employee Travel Status service
  • Two airline web services, American and Delta

The client initiates the BPEL process by sending an input message, TravelRequest. This is a synchronous call. Then the BPEL process invokes the Employee Travel Status service, sending the EmployeeTravelStatusRequest message. Because this is a synchronous invocation, it waits for the EmployeeTravelStatusResponse message. Then the BPEL process makes concurrent asynchronous invocations of both airline Web Services by sending them the FlightTicketRequest message. Both airline Web Services make a callback, sending the TravelReponse message. The BPEL process then selects the more appropriate airline and returns the reply message TravelResponse to the initial client. See the following sequence diagram:

In real-world scenarios, we do not define synchronous BPEL processes that use asynchronous Web Services, since the client may have to wait an arbitrarily long time. We would rather select an asynchronous BPEL process. In this example, we use the synchronous example to maintain simplicity. The next section shows how to define an asynchronous BPEL process.

Understanding and knowing the exact details of a business process is crucial. Otherwise, we will not be able to specify it using BPEL.

Now we are ready to start writing the BPEL process definition. Each BPEL definition contains at least four main parts:

  • The initial
    root element with the declaration of namespaces
  • The definition of partner links, using the
    element
  • The declaration of variables, using the element
  • The main body where the actual business process is defined; this is usually a that specifies the flow of the process

BPEL process outline

We start with an empty BPEL process outline that presents the basic structure of each BPEL process definition document:

<process name="Travel" ... >
<partnerLinks>
<!-- The declaration of partner links -->
</partnerLinks>
<variables>
<!-- The declaration of variables -->
</variables>

<sequence>
<!-- The definition of the BPEL business process main body -->
</sequence>
</process>

Let us first add the required namespaces. Here we have to define the target namespace and the namespaces to access the Employee and Airline WSDLs and the BPEL process WSDL. We also have to declare the namespace for all the BPEL activity tags (here the default namespace, so we do not have to qualify each BPEL tag name). The BPEL activity namespace must be http://docs.oasis-open.org/wsbpel/2.0/ process/executable


<process name="Travel"
targetNamespace="http://packtpub.com/bpel/travel/"
xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/executable"
xmlns:trv="http://packtpub.com/bpel/travel/"
xmlns:emp="http://packtpub.com/service/employee/"
xmlns:aln="http://packtpub.com/service/airline/" >
...

Partner links

Next we have to define the partner links. Partner links define different parties that interact with the BPEL process. Each partner link is related to a specific partnerLinkType that characterizes it. Each partner link also specifies up to two attributes:

  • myRole: Indicates the role of the business process itself
  • partnerRole: Indicates the role of the partner

The partner link can specify a single role, which is usually the case with synchronous request/response operations. In our example, we define four roles. The first partner link is called client and is characterized by the travelLT partner link type. The client invokes the business process. We need to specify the myRole attribute to describe the role of the BPEL process. In our case, this is the travelService.

...
<partnerLinks>
<partnerLink name="client"
partnerLinkType="trv:travelLT" myRole="travelService"/>
...

The second partner link is called employeeTravelStatus and is characterized by the employeeLT partner link type. It is a synchronous request/response relationship between the BPEL process and the service; we again specify only one role. This time it is the partnerRole because we describe the role of the service, which is a partner to the BPEL process.

...
<partnerLink name="employeeTravelStatus"
partnerLinkType="emp:employeeLT"
partnerRole="employeeTravelStatusService"/>
...

The last two partner links correspond to the airline services. Because they use the same type of service, we specify two partner links based on a single partner link type, flightLT. Here we have asynchronous callback communication; therefore, we need two roles. The role of the BPEL process (myRole) to the airline web service is airlineCustomer, while the role of the airline (partnerRole) is airlineService.

...
<partnerLink name="AmericanAirlines"
partnerLinkType="aln:flightLT"
myRole="airlineCustomer"
partnerRole="airlineService"/>

<partnerLink name="DeltaAirlines"
partnerLinkType="aln:flightLT"
myRole="airlineCustomer"
partnerRole="airlineService"/>
</partnerLinks>

Variables for the Travel Process

Variables are used to store messages and to reformat and transform them. We usually need a variable for every message sent to the partners and received from the partners. Looking at the sequence diagram, this would mean eight variables for our example. However, notice that the messages sent to both Airline Services are identical. So, we only need seven variables. Let's call them TravelRequest, EmployeeTravelStatusRequest, EmployeeTravelStatusResponse, FlightDetails, FlightResponseAA, FlightResponseDA, and TravelResponse.

For each variable we have to specify the type. We can use a WSDL message type, an XML schema simple type, or an XML schema element. In our example, we use WSDL message types for all variables:

...
<variables>
<!-- input for this process -->
<variable name="TravelRequest"
messageType="trv:TravelRequestMessage"/>
<!-- input for the Employee Travel Status service -->
<variable name="EmployeeTravelStatusRequest"
messageType="emp:EmployeeTravelStatusRequestMessage"/>
<!-- output from the Employee Travel Status service -->
<variable name="EmployeeTravelStatusResponse"
messageType="emp:EmployeeTravelStatusResponseMessage"/>
<!-- input for American and Delta services -->
<variable name="FlightDetails"
messageType="aln:FlightTicketRequestMessage"/>
<!-- output from American Airlines -->
<variable name="FlightResponseAA"
messageType="aln:TravelResponseMessage"/>
<!-- output from Delta Airlines -->
<variable name="FlightResponseDA"
messageType="aln:TravelResponseMessage"/>
<!-- output from BPEL process -->
<variable name="TravelResponse"
messageType="aln:TravelResponseMessage"/>
</variables>
...

WS-BPEL 2.0 for SOA Composite Applications with Oracle SOA Suite 11g Define, model, implement, and monitor real-world BPEL business processes with SOA powered BPM for Oracle SOA Suite with this book and eBook
Published: September 2010
eBook Price: $41.99
Book Price: $69.99
See more
Select your format and quantity:

Read more about this book

(For more resources on BPEL, SOA and Oracle see here.)

BPEL process main body

The process main body may contain only one top-level activity. Usually, this is a that allows us to define several activities that will be performed sequentially. Other possibilities for this activity include , through which several activities can be performed concurrently. We can also specify to indicate loops, or to define nested activities. However, we usually use and nest other activities within the sequence.

Within the sequence, we first specify the input message that starts the business process. We do this with the construct, which waits for the matching message. In our case, this is the TravelRequest message. Within the construct, we do not specify the message directly. Rather we specify the partner link, the port type, the operation name, and optionally the variable that holds the received message for consequent operations.

We link the message reception with the client partner, and wait for the TravelApproval operation to be invoked on port type TravelApprovalPT. We store the received message in the TravelRequest variable as follows:

...
<sequence>

<!-- Receive the initial request for business travel from client -->
<receive name="ReceiveInitialRequest" partnerLink="client"
portType="trv:TravelApprovalPT" operation="TravelApproval"
variable="TravelRequest" createInstance="yes" />
...

As already mentioned, waits for the client to invoke the TravelApproval operation and stores the incoming message and parameters about the business trip into the TravelRequest variable. Here, the variable name is the same as the message name, but this is not necessary.

Next, we need to invoke the Employee Travel Status service. Before this, we have to prepare the input for this service. Looking at the WSDL of the Employee service, we can see that we have to send a message consisting of the employee part. We can construct such a message by copying the employee part of the message that the client sent. We write the corresponding assignment:

...
<!-- Prepare the input for the Employee Travel Status Service -->
<assign name="PrepareInputForEmplyeeWS">
<copy>
<from variable="TravelRequest" part="employee"/>
<to variable="EmployeeTravelStatusRequest" part="employee"/>
</copy>
</assign>
...

Now we can invoke the Employee Travel Status service. We make a synchronous invocation, for which we use the activity. We use the employeeTravelStatus partner link and invoke the EmployeeTravelStatus operation on the EmployeeTravelStatusPT port type. We have prepared the input message in the EmployeeTravelStatusRequest variable. Because it is a synchronous invocation, the call waits for the reply and stores it in the EmployeeTravelStatusResponse variable:

...
<!-- Synchronously invoke the Employee Travel Status Service -->
<invoke name="InvokeEmployeeWS"
partnerLink="employeeTravelStatus"
portType="emp:EmployeeTravelStatusPT"
operation="EmployeeTravelStatus"
inputVariable="EmployeeTravelStatusRequest"
outputVariable="EmployeeTravelStatusResponse" />
...

The next step is to invoke both Airline Web Services. Again, we first prepare the required input message (which is equal for both Web Services). The FlightTicketRequest message consists of two parts:

  • flightData: This is retrieved from the client message (TravelRequest)
  • travelClass: This is retrieved from the EmployeeTravelStatusResponse variable

Therefore, we write an assignment with two copy elements:

...
<!-- Prepare the input for AA and DA -->
<assign name="PrepareInputForAAandDA">
<copy>
<from variable="TravelRequest" part="flightData"/>
<to variable="FlightDetails" part="flightData"/>
</copy>
<copy>
<from variable="EmployeeTravelStatusResponse"
part="travelClass"/>
<to variable="FlightDetails" part="travelClass"/>
</copy>
</assign>
...

The input data includes the data that needs to be passed to the Airline Web Services. Since it is in the same format, we can pass it directly (using a simple copy). In the real world, we usually need to perform a transformation. We could do that using XPath expressions with , use a transformation service (such as an XSLT engine), or use the transformation capabilities provided by specific BPEL servers.

Now we are ready to invoke both Airline Web Services. We will make concurrent asynchronous invocations. To express concurrency, BPEL provides the activity. The invocation to each web service will consist of two steps:

  1. The activity is used for the asynchronous invocation.
  2. The activity is used to wait for the callback.

We use to group both activities. The two invocations differ only in the partner link name. We use AmericanAirlines for one and DeltaAirlines for the other. Both invoke the FlightAvailability operation on the FlightAvailabilityPT port type, sending the message from the FlightDetails variable.

The callback is received using the activity. Again, we use both partner link names. The activity waits for the FlightTicketCallback operation to be invoked on the FlightCallbackPT port type. We store the resulting message in the FlightResponseAA and the FlightResponseDA variables respectively:

...
<!-- Make a concurrent invocation to AA in DA -->
<flow name="InvokeAAandDA">
<sequence>
<!--Async invoke of the AA web service and wait for the callback-->

<invoke name="InvokeAA"
partnerLink="AmericanAirlines"
portType="aln:FlightAvailabilityPT"
operation="FlightAvailability"
inputVariable="FlightDetails" />
<receive name="ReceiveCallbackFromAA"
partnerLink="AmericanAirlines"
portType="aln:FlightCallbackPT"
operation="FlightTicketCallback"
variable="FlightResponseAA" />
</sequence>
<sequence>
<!--Async invoke of the DA web service and wait for the callback-->
<invoke name="InvokeDA"
partnerLink="DeltaAirlines"
portType="aln:FlightAvailabilityPT"
operation="FlightAvailability"
inputVariable="FlightDetails" />
<receive name="ReceiveCallbackFromDA"
partnerLink="DeltaAirlines"
portType="aln:FlightCallbackPT"
operation="FlightTicketCallback"
variable="FlightResponseDA" />
</sequence>
</flow>
...

At this stage of the process, we have two ticket offers. In the next step, we have to select one. For this, we use the activity:

...
<!-- Select the best offer and construct the TravelResponse -->
<if name="SelectBestOffer">

<condition>
$FlightResponseAA.confirmationData/aln:Price &lt;=
$FlightResponseDA.confirmationData/aln:Price
</condition>

<!-- Select American Airlines -->
<assign>
<copy>
<from variable="FlightResponseAA" />
<to variable="TravelResponse" />
</copy>
</assign>

<else>
<!-- Select Delta Airlines -->
<assign>
<copy>
<from variable="FlightResponseDA" />
<to variable="TravelResponse" />
</copy>
</assign>
</else>
</if>
...

In the element, we check whether the offer from American Airlines (FlightResponseAA) is equal or better than the offer from Delta (FlightResponseDA). For this, we access the BPEL variable from XPath using the $ operator. The price is located inside the confirmationData message part, which is the only message part, but we still have to specify it. We also have to specify the node to locate the price element. Here, this is a simple XPath 1.0 expression.

If the American Airlines offer is better than Delta (or equal), we copy the FlightResponseAA variable to the TravelResponse variable (which we finally return to the client). Otherwise, we copy the FlightResponseDA variable.

We have come to the final step of the BPEL business process—to return a reply to the client using the activity. Here we specify the same partner link as in the initial receive client. We also specify the same port type and operation name. The variable that holds the reply message is TravelResponse.

...
<!-- Send a response to the client -->
<reply name="SendResponse"
partnerLink="client"
portType="trv:TravelApprovalPT"
operation="TravelApproval"
variable="TravelResponse"/>
</sequence>
</process>

With this, we have concluded our first business process specification in BPEL. You can see that BPEL is not very complicated and allows a relatively easy and natural specification of business processes. The consumption of other services is also relatively easy if you are familiar with WSDL. In the next section, we modify our BPEL process to make it asynchronous.

Asynchronous BPEL example

Our first BPEL business process example was synchronous because this was the easiest case. However, in the real world, we will mostly use asynchronous processes. Most business processes are long running. It makes no sense for a client to wait (and be blocked) for the entire duration of the process. A much better alternative is to model the BPEL process as asynchronous. This means that the client invokes the process, and when the process completes, it performs a callback to the client. This has a few consequences:

  • For the BPEL process to be able to perform a callback to the client, the client must be a service and implement a certain port type (usually defined by the BPEL process WSDL)
  • The partner link type for the client will have to specify two roles
  • The BPEL process will not to the client. Rather it will the callback

Let us now focus on our business process and modify it for asynchronous invocation, presented in the next sequence diagram. We have to perform the following steps:

  1. Modify the BPEL process WSDL, where the operation invoked by the client will now have only the input message.
  2. Define the client port type and the operation, which the BPEL process will invoke for the callback. We will do this in the WSDL of the BPEL process.
  3. Modify the partner link type, where we will add the second role.
  4. Modify the BPEL process specification. We have to modify the partner link and replace the activity with an .

The modified sequence diagram is shown as follows. It is very similar to the previous example, except that the initial travel request is asynchronous and the final answer is delivered as a callback.

Modify the BPEL Process WSDL

The modified WSDL for the BPEL process will have to specify the TravelApprovalPT port type, which will now specify an input message only. It will also have to declare the ClientCallbackPT port type, used to return the result to the client (asynchronously, using a callback). This is shown in the following figure:

Let us first modify the TravelApprovalPT port type used for client interaction, which will now define only the input message:

...
<portType name="TravelApprovalPT">
<operation name="TravelApproval">
<input message="tns:TravelRequestMessage" />
</operation>
</portType>
...

Next we define the client callback port type (ClientCallbackPT) with the ClientCallback operation. The response message is TravelResponseMessage. Notice that the WSDL only specifies this port type, which is implemented by the client.

...
<portType name="ClientCallbackPT">
<operation name="ClientCallback">
<input message="aln:TravelResponseMessage" />
</operation>
</portType>
...

Modify partner link types

We need to modify the partner link type for the interaction with the BPEL process, called the travelLT link type. We have to add the second role, travelServiceCustomer, which characterizes the client to which the BPEL process will perform a callback on the ClientCallbackPT port type. This is done in the WSDL of the BPEL process:

<plnk:partnerLinkType name="travelLT">
<plnk:role name="travelService"
portType="tns:TravelApprovalPT" />
<plnk:role name="travelServiceCustomer"
portType="tns:ClientCallbackPT" />
</plnk:partnerLinkType>

Modify the BPEL process definition

Finally, we modify the BPEL process definition. Here we first have to modify the client partner link, where we have to specify the second role—the partnerRole. Here, this is travelServiceCustomer, which characterizes the BPEL process client.

<partnerLinks>
<partnerLink name="client"
partnerLinkType="trv:travelLT"
myRole="travelService"
partnerRole="travelServiceCustomer"/>
...

Next, we change the last activity of the BPEL process. We replace the activity with the callback. For the callback, we use the client partner link and invoke the ClientCallback operation on the ClientCallbackPT port type. The message signature has not changed, so we use the same variable as before, TravelResponse.

...
<!-- Make a callback to the client -->
<invoke name="SendResponse"
partnerLink="client"
portType="trv:ClientCallbackPT"
operation="ClientCallback"
inputVariable="TravelResponse" />
</sequence>
</process>

Our BPEL process is now asynchronous!

To execute a BPEL process, we need a runtime environment.

You can download both the synchronous and asynchronous BPEL process examples with the corresponding services from http://www.packtpub.com They can be deployed to the Oracle SOA Suite using JDeveloper.

Summary

In the above article we have covered:

  • BPEL business process example
  • Involved services
  • Employee Travel Status service
  • Airline service
  • WSDL for the BPEL process
  • Partner link types
  • Business process definition
  • BPEL process outline
  • Partner links
  • Variables for the Travel Process
  • BPEL process main body
  • Asynchronous BPEL example
  • Modify the BPEL Process WSDL
  • Modify partner link types
  • Modify the BPEL process definition

Further resources on this subject:


About the Author :


Marcel Krizevnik

Marcel Krizevnik is a researcher at the University of Maribor where he is preparing a Ph.D. in computer and information science. Marcel started his career as a software developer of chemistry information systems. Now, his main research areas are service-oriented architecture and cloud computing. He is also a member of SOA Competency Center and Cloud Computing Center. In the last three years, he has been involved in several SOA technology projects.

Matjaz B. Juric

Matjaz B. Juric holds a PhD in Computer and Information Science. He is a Full Professor at the University of Ljubljana and head of the Cloud Computing and SOA Competence Centre (http://www.soa.si). Matjaz is a Java Champion, IBM Champion, and Oracle ACE Director. He has more than 15 years of work experience. He has authored/co-authored "Do More with SOA Integration, WS-BPEL 2.0 for SOA Composite Applications, Oracle Fusion Middleware Patterns, Business Process Driven SOA using BPMN and BPEL, and Business Process Execution Language for Web Services "(English and French editions). He has also authored/co-authored "BPEL Cookbook: Best Practices for SOA-based integration and composite applications development" (award for best SOA book in 2007 by SOA World Journal), "SOA Approach to Integration, Professional J2EE EAI, Professional EJB, J2EE Design Patterns Applied", and .NET Serialization Handbook. He has published chapters in More Java Gems (Cambridge University Press) and in Technology Supporting Business Solutions (Nova Science Publishers). He has also published in several journals and magazines and presented at conferences. Matjaz has been involved in several large-scale projects. In cooperation with the IBM Java Technology Centre, he worked on performance analysis and optimization of RMI-IIOP, an integral part of the Java platform.

Books From Packt


Getting Started With Oracle SOA Suite 11g R1 – A Hands-On Tutorial
Getting Started With Oracle SOA Suite 11g R1 – A Hands-On Tutorial

BPEL PM and OSB operational management with Oracle Enterprise Manager 10g Grid Control
BPEL PM and OSB operational management with Oracle Enterprise Manager 10g Grid Control

Service Oriented Architecture: An Integration Blueprint
Service Oriented Architecture: An Integration Blueprint

Oracle Coherence 3.5
Oracle Coherence 3.5

Getting Started with Oracle BPM Suite 11gR1 – A Hands-On Tutorial
Getting Started with Oracle BPM Suite 11gR1 – A Hands-On Tutorial

Oracle Siebel CRM 8 Installation and Management
Oracle Siebel CRM 8 Installation and Management

Oracle Fusion Middleware Patterns
Oracle Fusion Middleware Patterns

EJB 3.0 Database Persistence with Oracle Fusion Middleware 11g
EJB 3.0 Database Persistence with Oracle Fusion Middleware 11g


No votes yet

Post new comment

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