Useful Document/resources For Begginners
this document is easily on net
WS-BPEL Guide
Last changed on Dec 10, 2004 by Matthieu Riou
What is this article about ?
This is an introduction to WS-BPEL that should give you a practical understanding of what you have to do to create a nice WS-BPEL process, dwelling on most important details. After reading this article you probably won't be able to write a WS-BPEL process from top to bottom. But you should have a pretty good notion of what can be done with it, what it involves and be familiar with the main elements of the grammar.
First things first, here are the answers to the most trivial questions:
What this new and unique acronym means? Web Services Business Process Execution Language.
What is WS-BPEL? It's an XML grammar (a W3C schema) defining and standardizing structures necessary for web services orchestration.
What does WS-BPEL? Well, actually nothing as it's just a grammar. But a WS-BPEL engine can do many things when executing your process. Like reacting to message reception, manipulating the message data, sending messages to web services and evaluating expressions.
Where does it come from? It has been written by IBM, BEA Systems and Microsoft. Siebel and SAP joined these three and the specification has bee donated to OASIS.
Where does WS-BPEL fit? It's a very good candidate to add an orchestration layer to a Service Oriented Architecture. It will make your services collaborate nicely and will encapsulate the cross-service business logic. It will also help you to introduce long-living transactions.
Now that the introductory questions have been answered and before going any further I would like to clarify one thing about WSDL (I voluntarily wrote WSDL here, it's not a weird typo). WS-BPEL heavily relies on WSDL to describe the web services it is interacting with (we will see that soon) but that doesn't mean that it can only interact with services using XML(SOAP)/HTTP. WSDL introduces bindings which are the declaration of your services underlying communication medium. Bindings can be declared for local Java, JMS, RMI or anything you like (you might want to check Apache WSIF ). So a WS-BPEL engine using the right bindings could very well invoke many different services.
So let's see how we are going to take a look at WS-BPEL. First, I'm going to give a very simple and classic example, just to give you a taste of what can be done with WS-BPEL. Then I'll introduce briefly its main activities. We'll see how to handle your process data and manipulate it and also how a particular process execution can be identified among all others. Finally we'll talk about how WS-BPEL introduces long-living transactions.
A very simple yet demonstrative example
After reading this chapter, most of you will probably think that the example I'm going to use is too simple and not realistic. I agree. But my goal here is just to give you a flavor of how WS-BPEL can be used, a realistic example would take more than all this article by itself.
Now, you are the owner of a small bank granting loans to some of your customers. You have sales offices creating new customer contracts. You also have a web site and customers can directly ask for a loan online for small amounts. But before accepting a contract, some verifications are necessary. Those verifications are done using a risk assessment system maintained by a third party and by an in-house system that files the most tough requests. Loan specialists are part of your staff and then use this in-house system to take the final decision.
So here is, step by step, the process that must be followed:
1. A loan request is issued, either from your web site of from one of your agencies. This request is made for a customer and for a certain amount.
2. A risk assessment system must be contacted to check whether the risk associated with the customer asking for the loan is high or low (probably based on his credit history).
1. If the loan amount is lower than $10,000 and the risk associated to the customer is low, the loan is directly approved (which saves time).
2. Otherwise, the loan request must be filed in your in-house system.
1. A loan specialist checks the request and gives his final decision.
2. The in-house system let you know the specialist's decision.
3. The response is sent to the customer.
So how those pieces would be implemented in a "WS-BPEL aware" architecture? Here we go:
One message triggered by your web site or your sales system and targeted at your process web service. It would hold at least the customer's name and the loan amount.
One message triggered by the WS-BPEL engine to the risk assessment system to ask for the risk associated with the customer. If you pay your bills correctly, an answer message from this message should be expected.
If needed, one message from the WS-BPEL engine to your in-house system to fill the loan request.
One message from your in-house system to the process web service to give it the loan specialist's answer.
Finally, one message back to your web site or to your sales system to give the final answer.
One thing some of you probably already noticed is that when talking about the process I mentioned the "process web service". That's right, every process created inside a WS-BPEL engine is published as a web service with its own endpoint. When you want to send a message to your process, you actually send it to this web service.
So now that you have a better idea of what it would take to implement this process in WS-BPEL, it's time to step back a bit.
Private vs. Public Processes
It's quite important to differentiate private and public processes (they are called executable and abstract in WS-BPEL). It is the same kind of opposition as between orchestration and choreography and it has a great impact on your architecture.
Private processes manage services inside a given organization. They act as a service themselves and are centralized. As in an orchestra, there is a chief conductor (the process engine). Public processes manage services across several organizations. Each organization knows about it's own part of the process but doesn't know anything about the activities executed by other parties (for obvious confidentiality reasons). It's a peer-to-peer approach where you know the incoming and the outgoing messages, but nothing about what is done before, after or even meanwhile.
WS-BPEL is quite good to handle private processes but doesn't perform so well for public ones (don't shoot me!). I have a feeling that even the members of the Oasis committee working on WS-BPEL don't know too much what to do with those. But actually, service choreography (public services) is not completely mature yet in terms of standards and market acceptance where as orchestration already has a widely embraced specification (WS-BPEL, in case you didn't realize) and many commercial implementations as well as open source ones (you may want to check Twister ). So good news, what you are going to learn in this article might prove useful.
After those high-level considerations, we'll now look into WS-BPEL guts to see what's there and what we could use to build our process.
WS-BPEL Activities
In WS-BPEL, everything being part of your process body is an activity. There are basic activities (the ones that do something) and structured activities (the ones that organize basic activities without doing anything by themselves, just like your boss).
Basic activities
Invoking a web service is as simple as that:
<invoke partnerLink="riskAssessor" portType="assessor" operation="assess"/>
Pretty simple isn't it? In our initial example this declaration would be used to invoke the risk assessment system. Well, I'm actually cheating, you'll see later that you usually need a bit more (like input and output data) but this is a valid invocation.
To wait for an incoming message, you'll write:
<receive partnerLink="inhouseSystem" portType="inhousePort" operation="registerLoanRequest"/>
That would be used to wait for the loan specialists' answer after registering the loan request in your in-house system. Now let's say that you want to send an immediate synchronous answer to this "receive". You'd write, after the receive:
<reply partnerLink="inhouseSystem" portType="inhousePort" operation="registerLoanRequest"/>
But how exactly does a WS-BPEL engine know, upon reception of a message, if it has to trigger the creation of a new process execution (a process instance)? Well, there's an attribute just for that: "createInstance".
<receive partnerLink="loanRequester" portType="loanProcess" operation="processLoanRequest" createInstance="true"/>
These 3 declarations use common attributes: partnerLink, portType and operation. If you know WSDL, you are already familiar with the port types and operations. Partner links have been introduced in WS-BPEL to model a two-way interaction between a process and a partner (a web service or another process). It lets you define the role of each of the two party in the interaction.
There are two more basic activities that could prove useful (or at least one of the two):
<wait until="'2002-12-24T18:00+01:00'"/>
<empty/>
Structured activities
To start with, 3 basic ones: sequence, switch and while. If their behavior is not clear yet, here are examples:
<sequence>
<receive .../>
<invoke .../>
<invoke .../>
</sequence>
<switch xmlns:inventory="http://supply-chain.org/inventory" xmlns:FLT="http://example.com/faults">
<case condition= "bpws:getVariableProperty(stockResult,level) > 100">
do something
</case>
<case condition="bpws:getVariableProperty(stockResult,level) >= 0">
do something else
</case>
<otherwise>
do the last thing
</otherwise>
</switch>
<while condition="10 < bpws:getVariableData('loopVar', 'main', '/counter')">
<assign>
<copy>
<from expression="bpws:getVariableData('loopVar', 'main', '/counter') + 1"/>
<to variable="loopVar" part="main" query="/counter"/>
</copy>
</assign>
</while>
Another structured activity is 'pick'. It's just like several receive activities waiting at the same time with an additional alarm construct to avoid waiting forever the occurrence of a message:
<pick>
<onMessage partnerLink="" portType="" operation="">
do something
</onMessage>
<onMessage partnerLink="" portType="" operation="">
do something else
</onMessage>
<onAlarm until="2004-12-31T23:59:00">
hey, what the hell are you waiting for?
</onAlarm>
<pick>
Like the receive activity, it's possible to declare a 'createInstance' attribute on the pick element to trigger the creation of a new process instance.
Finally, for those who found all those activities way too structured and were missing a bit of anarchy, WS-BPEL introduced a flow activity. You basically declare all your activities as you like and then create links that take those activities as origin and target. The flow is also the only way to enable the execution of several parallel branches.
Process Data
To handle the process execution data, WS-BPEL introduces a new and unique concept: variables
Ok, that was just a bad attempt to keep you interested. Here is the context: your process engine must receive and send messages as defined by web services WSDL descriptions. To be able to do anything useful it must retain those messages and let you manipulate their content to create new messages or influence the process flow in variables. Therefore variables hold the state of a process execution. WS-BPEL variables can either hold a WSDL message or an arbitrary XML structure defined by a schema.
An example for the declaration of a variable that can hold a WSDL message (the first stanza comes from the WSDL description, the second is a part of the process definition):
<message name="creditInformationMessage">
<part name="firstName" type="xsd:string"/>
<part name="lastName" type="xsd:string"/>
<part name="amount" type="xsd:integer"/>
</message>
<variable name="requestLoan" messageType="creditInformationMessage"/>
So now, how do I stuff an incoming message into this variable? Here is the stuffing:
<receive partnerLink="loanRequester" portType="loanProcess" operation="processLoanRequest" variable="requestLoan"/>
Hey hey! That's our old receive! A variable attribute can be specified for a receive to hold the incoming message. For a reply, there's also a variable attribute to give the content of the message to send. And for an invoke, there's an inputVariable attribute to give the variable to send and an outputVariable to hold the response (for a synchronous invocation).
We have variables to hold our message and we know how to give them a value upon reception of a message. But how do you initialize a variable when you want to send a message using it? How do you build a variable using parts of other variables? The answer is assignment. There's an additional activity I didn't mention yet (yes, I'm holding information) named assign. It lets you "copy and paste" the whole content of a variable, only a WSDL part in a message or even just an element (using Xpath). Again, examples are better than idle words:
<assign>
<copy>
<from variable="ob1"/>
<to variable="knob"/>
</copy>
<copy>
<from variable="userInfo" part="homeAddress"/>
<to variable="address"/>
</copy>
<copy>
<from variable="house" part="bathroom" query="/shower/soap"/>
<to variable="cleaningAgent"/>
</copy>
<copy>
<from>hey you</from>
<to variable="song" part="title"/>
</copy>
</assign>
Once your variable has been set correctly, you can simply use it as inputVariable for an invoke.
There's still one mystery unsolved in the way you can use variables in WS-BPEL: referencing them in expressions. Let's say you have a variable holding a specific value and want to use this value in the condition of a switch case, how do we do that? By using two functions:
bpws:getVariableProperty ('variableName', 'propertyName')
bpws:getVariableData ('variableName', 'partName'?, 'locationPath'?)
The first function accepts the name of your variable and a property (we'll introduce property later but right now you just need to know that a property is a named XPath expression). The second accepts your variable, an optional part and an optional XPath expression relative to the part root.
It's now time to see your first complete WS-BPEL example. It triggers the execution of a process upon reception of a message and iterates over a value contained in the message until 10. It's a very stupid example and it's probably the last thing you want to do with WS-BPEL (just as a reminder, WS-BPEL is used to orchestrate web services, not iterate over a value) but it illustrates almost everything we talked about in this paragraph.
<?xml version='1.0' encoding="UTF-8"?>
<process name="loop"
targetNamespace="http://www.smartcomps.org/twister/example/loop/process/"
xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
xmlns:def="http://www.smartcomps.org/twister/examples/loop/service/"
abstractProcess="no">
<variables>
<variable name="loopVar" type="loopVarType"/>
</variables>
<correlationSets>
<correlationSet name="counterCorrel" properties="def:counterId"/>
</correlationSets>
<sequence>
<receive partnerLink="loopPartner" portType="loopPort" operation="loopOp"
variable="loopVar" createInstance="true">
<correlations>
<correlation set="counterCorrel" initiate="yes"/>
</correlations>
</receive>
<while condition="10 > bpws:getVariableData('loopVar', 'main', '/counter')">
<assign>
<copy>
<from expression="bpws:getVariableData('loopVar', 'main', '/counter') + 1"/>
<to variable="loopVar" part="main" query="/counter"/>
</copy>
</assign>
</while>
</sequence>
</process>
As you probably already realized, data manipulation can quickly become a bit verbose. The WS-BPEL Technical Committee is currently working on it to have something easier for WS-BPEL 2.0.
Correlation
Correlation is a notion that can be a bit hard to grasp at first but is very important. So hang on and I'll do my best to be even more clear (somehow) than usually. During its execution, a process has to interact with several different services. This interaction is stateless so there is no way to make sure you will be addressed to a particular instance of a service. So let's imagine you own a wine store and have a web site allowing users from all over the world to order cheap and very good French wine. A service provided by your bank does the billing for you and you also use a shipper to send the orders all over the world. When a user places an order online, your web site generates an order id. But your bank doesn't know anything about your order id, it creates its own billing id corresponding to your order and you always must use this billing id when interacting with your bank (to confirm the transaction just after shipment for example). The shipper also creates his own shipment id that will be used when he confirms that the order has been sent.
You want to use a WS-BPEL engine to handle those tasks automatically and orchestrate all the services (there's probably much more than three services and many steps involved). That's a really good idea!!! But how do you deal with all these different ids ? Yep, you guessed it: correlation. How does it work? A correlation is an unique way to identify the interaction of your process execution with a given party. A correlation is a list of property elements and a property element is a named XPath expression. This XPath expression must select a value in the exchanged messages that will be the value of the correlation for this particular message. So for our previous example we would define the following elements:
<property name="billId" type="xsd:string"/>
<propertyAlias propertyName="billId" messageType="createBillMessage" part="billInfo" query="billId"/>
<propertyAlias propertyName="billId" messageType="confirmTransactionMessage" part="billId"/>
<property name="shipId" type="xsd:string"/>
<propertyAlias propertyName="shipId" messageType="shipMessage" part="shipId"/>
<correlationSets>
<correlationSet name="bankCorrelation" properties="billId"/>
<correlationSet name="shipperCorrelation" properties="shipId"/>
</correlationSets>
A correlation can be composed of more than one property (separated by spaces). A property can also have several aliases for each type of message the correlation is used for.
Usually a correlation is declared for each actor your process has to communicate with. The correlation is initiated during the first message exchange between your process execution and a party and is reused anytime your process execution sends a message to this party.
Compensation
I'm not going to detail this chapter as much as I did for the previous ones. This article is already far too long (and therefore too boring). Talking about compensation in a detailed manner would require another article like this one. But to whet your appetite, I'll tell you what its is and what it is the problem it has been designed to solve.
Compensation is related to error handling. WS-BPEL processes are usually long-lasting (there could be days between 2 activities), they use asynchronous messages and interact with several different services. Introducing the concept of ACID transactions in this context is quite tough. Each of the services involved can locally use its own transaction but it's impossible within your process to control them (and you probably don't want to). So what can you do if you have three asynchronous operations, like 3 invoke / receive couples, that must be executed in an "all or nothing" fashion? How to cancel the two first operations that have already been committed if the third fails?
Compensation is basically a set of activities attempting to cancel operations that have already been completed inside an unit of work. If an activity fails or a fault is thrown inside this unit of work, this set of activities is supposed to roll back everything that has been already completed in the unit of work in a way specific to your business case. You are the only one who really knows what to do if something goes wrong so you have to provide the necessary operations.
But this system has important drawbacks:
It is your responsibility to execute the right activities to handle the cancellation.
All the services you are interacting with must support a way to rollback a previously committed transaction (most probably requiring some hard coding).
Conclusion
WS-BPEL has been a bit criticized principally for its absence of human participant interaction (as in conventional workflows), everything is a service. But whether you like it or not, it's already standard and if you use it for what it is good at, a pretty good one. Besides it's a good step in the right direction to standardize the BPM - SOA - 'call it what you like' space. And you can always rely on good products like Twister to introduce Worklist functionalities (remember, always a bit of marketing in a conclusion).
Resources
WS-BPEL Specification: http://www-106.ibm.com/developerworks/library/ws-bpel/
Oasis WS-BPEL Technical committee: http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsbpel
Twister WS-BPEL Open Source Implementation: http://www.smartcomps.org/twister