BPEL (Business Process Execution Language) has become one of the most important technologies of SOA (service-oriented architecture) and enables easy and flexible composition of services into business processes. BPEL is particularly important because it introduces a new concept into application development—programming-in-the-large. This concept enables us to develop processes quickly by defining the order in which services will be invoked. This way, applications (and information systems) become more flexible and can better adapt to the changes in business processes.

Business processes are usually of dynamic nature. Companies have to improve and modify, act in an agile manner, optimize, and adapt processes to improve the responsiveness of the whole company. Every change and improvement in a business process has to reflect in applications that provide support for them. Although this requirement may not sound very difficult to fulfill, the real-world situation shows us a different picture. Changing and modifying applications is often a difficult job, which requires time. Therefore applications cannot react instantly to changes in business processes—rather, they require some time to implement, test, and deploy the modifications.

Making information systems more flexible and adaptable to changes, and better aligned with business processes is the major promise of SOA. In this article, I show why BPEL is so important and demonstrate how to develop a BPEL process.

Service-oriented approach

The SOA approach for efficient automation of business processes requires:

  • Standardized way to expose and access the functionality of applications as services
  • Enterprise bus infrastructure for communication and management of services, including message interception, routing, transformation, etc.
  • Specialized language for composition of exposed functionalities of applications into business processes

The first requirement is fulfilled by the latest distributed architecture—Web services. The second requirement is fulfilled by the ESB (enterprise service bus), which provides support for centralized, declarative, and well-coordinated management of services and their communications. The third requirement, composition of services into processes, is fulfilled by BPEL, the commonly accepted specialized language for business process definition and execution.

A business process, as seen by BPEL, is a collection of coordinated service invocations and related activities that produce a result, either within a single organization or across several. For example, a business process for planning business travels will invoke several services. In an oversimplified scenario, the business process will require us to specify the employee name, destination, dates, and other travel details. Then the process will invoke a Web service to check the employee status. Based on the employee status, it will select the appropriate travel class. Then it will invoke Web services of several airline companies (such as American Airlines, Delta Airlines, etc.) to check the airfare price and buy the one with the lowest price.

For the clients, the BPEL process will expose its functionality in the same way as any other Web service. From the client perspective, it will look exactly like any other Web service. This is important and useful, as it allows us to compose services into simple processes, simple processes into more complex processes, and so on. This also means that each BPEL process will be described with a WSDL (Web Services Description Language) description.

Core concepts

BPEL is an XML-based language. A BPEL process consists of steps. Each step is called an activity. BPEL supports primitive and structure activities. Primitive activities represent basic constructs and are used for common tasks, such as those listed below:

  • Invoking Web services, using <invoke>
  • Waiting for the request, using <receive>
  • Manipulating data variables, using <assign>
  • Indicating faults and exceptions, using <throw>, etc.

We can then combine these activities into more complex algorithms that specify the steps of a business process. To combine primitive activities, BPEL supports several structure activities. The most important are:

  • Sequence (<sequence>) for defining a set of activities that will be invoked in an ordered sequence
  • Flow (<flow>) for defining a set of activities that will be invoked in parallel
  • Case-switch construct (<switch>) for implementing branches
  • While (<while>) for defining loops, etc.

As we will see, BPEL is not that different from programming languages, such as Java. But we will see that BPEL differs from Java and supports the characteristics of business processes. BPEL also provides fault and compensation handlers, event handlers, and correlation sets. It provides means to express complex parallel flows. It also makes it relatively easy to call asynchronous operations and wait for callbacks.

BPEL processes require a runtime environment—a BPEL server, which gives us good control over their execution. Typically, BPEL servers provide control over process instances that are executing and those that have finished. They support long-running processes and can dehydrate process state to save resources. Some servers provide control over process activities and allow their monitoring. Finally, using a BPEL server, all our processes are deployed centrally, which simplifies maintenance. All this makes the BPEL server the preferred environment for running and managing processes.

Choosing the right BPEL server can be quite difficult, however, as there are several choices. Some of the most popular BPEL servers that are based on Java EE (Sun's new name for J2EE) include Oracle BPEL Process Manager, IBM WebSphere Business Integration Server Foundation, BEA WebLogic Integration, and AquaLogic. There are also at least four open source BPEL servers available: ActiveBPEL Engine, FiveSight PXE, bexee, and Apache Agila.

Example process

Let us now look at an example BPEL process for business travels that we have described above. We will develop an asynchronous process that will use a synchronous call to check the employee travel status and two asynchronous calls to acquire the plane ticket prices. The figure below shows the overall structure of our process. On the left, we see the client that invokes the process. The process first calls the employee travel status Web service. Then it invokes both airlines' Web services concurrently and asynchronously. This means that the process will have to implement the callback operation (and a port type), through which the airlines will return the flight ticket confirmation. Finally, the process returns the best airline ticket offer to the client. In this example, to maintain simplicity, we will not implement any fault handling, which is crucial in real-world scenarios.

Let us now write the BPEL code. We start with the process declaration—the root element, where we define the process name and the namespaces:

 <process name="Travel" 
   targetNamespace="http://packtpub.com/bpel/travel/" 
   xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/" 
   xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/" 
   xmlns:trv="http://packtpub.com/bpel/travel/" 
   xmlns:emp="http://packtpub.com/service/employee/" 
   xmlns:aln="http://packtpub.com/service/airline/" > 

Next, we have to define the partner links. Partner links define different parties that interact with the BPEL process. This includes all Web services that will be invoked and the client of the process. Each partner link specifies up to two attributes: myRole that indicates the role of the business process itself and partnerRole that indicates the role of the partner. In our example, we define four partner links:

 <partnerLinks> 
<partnerLink name="client" 
   partnerLinkType="trv:travelLT" 
   myRole="travelService" 
   partnerRole="travelServiceCustomer"/> 
<partnerLink name="employeeTravelStatus" 
   partnerLinkType="emp:employeeLT" 
   partnerRole="employeeTravelStatusService"/> 
<partnerLink name="AmericanAirlines" 
   partnerLinkType="aln:flightLT" 
   myRole="airlineCustomer" 
   partnerRole="airlineService"/> 
<partnerLink name="DeltaAirlines" 
   partnerLinkType="aln:flightLT" 
   myRole="airlineCustomer" 
   partnerRole="airlineService"/> 
</partnerLinks> 

To store messages and to reformat and transform them, we need variables. Usually we use a variable for every message sent to the Web services and received from them. In our example, we will need a few variables. 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 web service --> 
   <variable name="EmployeeTravelStatusRequest" messageType="emp:EmployeeTravelStatusRequestMessage"/> 
   <!-- output from the Employee Travel Status web service --> 
   <variable name="EmployeeTravelStatusResponse" messageType="emp:EmployeeTravelStatusResponseMessage"/> 
   <!-- input for American and Delta web 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> 

Now we are ready to write the main process body. It contains only one top-level activity. Usually, this is a <sequence> that allows us to define several activities that will be performed sequentially. Within the sequence, we first specify the input message that starts the business process. We do this with the <receive> construct, which waits for the matching message. In our case, this is the TravelRequest message. Within the <receive> 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:

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

Next, we need to invoke the Employee Travel Status Web service. Before this, we have to prepare the input for this Web service. We can construct such a message by copying the employee part of the message that the client sent. Now we can invoke the Employee Travel Status Web service. We make a synchronous invocation, for which we use the <invoke> 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:

 

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

<!-- Synchronously invoke the Employee Travel Status Web Service --> <invoke 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). We will make concurrent asynchronous invocations. To express concurrency, BPEL provides the <flow> activity. The invocation to each Web service will consist of two steps:

  1. The <invoke> activity is used for the asynchronous invocation
  2. The <receive> activity is used to wait for the callback

We use <sequence> to group both activities. The two invocations differ only in the partner link name. We use AmericanAirlines for one and DeltaAirlines for the other:

Page 2 of 2
 

<!-- Make a concurrent invocation to AA in DA -->

<flow>

<sequence> <!-- Async invoke of the AA web service and wait for the callback -->

<invoke partnerLink="AmericanAirlines" portType="aln:FlightAvailabilityPT" operation="FlightAvailability" inputVariable="FlightDetails" />

<receive partnerLink="AmericanAirlines" portType="aln:FlightCallbackPT" operation="FlightTicketCallback" variable="FlightResponseAA" />

</sequence> ...

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

 

<switch>

<case condition="bpws:getVariableData('FlightResponseAA','confirmationData', '/confirmationData/aln:Price') <= bpws:getVariableData('FlightResponseDA','confirmationData', '/confirmationData/aln:Price')">

<!-- Select American Airlines --> ... ... </case>

<otherwise> <!-- Select Delta Airlines --> ... </otherwise> </switch>

We have come to the final step of the BPEL business process—to return a reply to the client using the callback to the client:

 

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

</process>

Conclusion

We have seen that BPEL is one of the most important cornerstones of SOA. It differs from common programming languages, such as Java, and is relatively easy to learn and use. Because BPEL has been designed specifically for definition of business processes, it provides good support for various specifics of business processes, such as support for long running transactions, compensation, event management, correlation, etc. BPEL is well suited for use with the Java EE platform, and many BPEL servers build on top of it. Java developers, particularly those who are involved in the development of enterprise applications and SOA, should therefore take a closer look at BPEL and start using the benefits it provides.

Dr Matjaz B. Juric is a professor at the University of Maribor. He is coauthor of the book Business Process Execution Language for Web Services, 2nd Edition, and the coauthor of the BPEL Cookbook, both published by Packt Publishing, and several other books, articles, and conference presentations. He is also the author of courses offered by BPELmentor.com, a training, mentoring, and consulting company.

Learn more about this topic