Wednesday, September 7, 2011

Writing a BPEL compensation handler

Compensation handling plays an important role in Business Process Management. It specifies how to undo a particular task which is not completed due to some error. Let’s take an example.
eg - Take a simple travel booking process which includes three parallel sub-tasks as follows.
Travel Booking Process

Now let’s assume hotel and taxi booking were successful. But couldn't book the flight. Now the “Book Hotel” and “Book Taxi” sub tasks should be compensated in order to mitigate the loss.

In WS-BPEL 2.0, compensation handling is specified using <compensationHandler/>. And <compensateScope/> or <compensate/> can be used to trigger the <compensationHandler/>.

Let’s take a look at the how a compensation handler can be implemented.
The easiest way is to add <compensationHandler/> in-line with <invoke/> activity. So when a fault occur; the in-line <compensationHandler/> is triggered. 
eg -
<invoke partnerLink="ReservationPL"
portType="tns:ReservationPT"
operation="reserve"
inputVariable="reserveInput"
outputVariable="reserveOutput">
<correlations>
<correlation set="ReserveOrder" initiate="yes"
pattern="request"/>
</correlations>
<compensationHandler>
<invoke partnerLink="ReservationPL"
portType="tns:ReservationPT"
operation="cancelReserve"
inputVariable="reserveOutput"
outputVariable="getConfirmation">
<correlations>
<correlation set="ReserveOrder" pattern="request"/>
</correlations>
</invoke>
</compensationHandler>
</invoke>
view raw gistfile1.xml hosted with ❤ by GitHub

The other method enables to compensate a specific scope using <compensationHandler/>. Here the <faultHandlers/> in the parent scope is used to trigger the <compensationHandler/> in the immediate child scope. For detailed descriptions on how exactly to trigger a <compensationHandler/> refer “12.4.3. Invoking a Compensation Handler” in WS-BPEL 2.0 specification.
eg -
<scope name="ReservationProcess">
...
<scope name="ReserveCarScope">
<sequence name="ReserveCar">
<empty name="Empty2"></empty>
<assign validate="no" name="AssignReserveCarActivity">
<copy>
<from>
<literal xml:space="preserve">1</literal>
</from>
<to variable="CarReservationActivity"></to>
</copy>
</assign>
</sequence>
<compensationHandler>
<sequence>
<assign validate="no" name="AssignCarReservatoinCompensated">
<copy>
<from>
<literal xml:space="preserve">1</literal>
</from>
<to variable="CarReservationCompensated"></to>
</copy>
</assign>
</sequence>
</compensationHandler>
</scope>
...
<faultHandlers>
<catch faultName="tns:ReserveFlightFailed">
<sequence>
<compensateScope name="CompensateReserveCar"
target="ReserveCarScope"></compensateScope>
</sequence>
</catch>
</faultHandlers>
</scope>
view raw gistfile1.xml hosted with ❤ by GitHub

We have added a sample compensation handler which is an implementation of a simple “Flight reservation process” to WSO2 BPS BPEL-2.0 sample repository.

No comments: