Scopes in Advanced BPEL

Exclusive offer: get 50% off this eBook here
WS-BPEL 2.0 for SOA Composite Applications with IBM WebSphere 7

WS-BPEL 2.0 for SOA Composite Applications with IBM WebSphere 7 — Save 50%

Define, model, implement, and monitor real-world BPEL 2.0 business processes with SOA-powered BPM for IBM WebSphere 7 with this book and eBook

$41.99    $21.00
by Matjaz B. Juric | October 2010 | BPEL Enterprise Articles IBM SOA

This article by Matjaz B. Juric, author of the book WS-BPEL 2.0 for SOA Composite Applications with IBM WebSphere 7, addresses the problems identified in the previous article, Fault Handling and Signaling in Advanced BPEL, where we discussed the various aspects of fault handling and signaling in BPEL.

In this article, we will cover:

  • Examples
  • Isolated scopes

WS-BPEL 2.0 for SOA Composite Applications with IBM WebSphere 7

WS-BPEL 2.0 for SOA Composite Applications with IBM WebSphere 7

Define, model, implement, and monitor real-world BPEL 2.0 business processes with SOA-powered BPM

  • Develop BPEL and SOA composite solutions with IBM's WebSphere SOA platform
  • Automate business processes with WS-BPEL 2.0 and develop SOA composite applications efficiently
  • Detailed explanation of advanced topics, such as security, transactions, human workflow, dynamic processes, fault handling, and more—enabling you to work smarter

 

Appendix

        Read more about this book      

(For more resources on BPEL, see here.)

Scopes provide a way to divide a complex business process into hierarchically organized parts—scopes. Scopes provide behavioral contexts for activities. In other words scopes address the problem that we identified in the previous article and allow us to define different fault handlers for different activities (or sets of activities gathered under a common structured activity, such as <sequence> or <flow>). In addition to fault handlers, scopes also provide a way to declare variables and partner links that are visible only within the scope. Scopes also allow us to define local correlation sets, compensation handlers, event handlers, termination handler, and message exchanges.

The following code excerpt shows how scopes are defined in BPEL. We can specify <partnerLinks>, <messageExchanges>, <variables>, <correlationSets>, <faultHandlers>, <compensationHandler>, <terminationHandler>, and <eventHandlers> locally for the scope. All are optional:

<scope>
<partnerLinks>
<!-- Partner link definitions local to scope. -->
</partnerLinks>
<messageExchanges>
<!-- Message exchanges local to scope.-->
</messageExchanges>
<variables>
<!-- Variable definitions local to scope. -->
</variables>
<correlationSets>
<!-- Correlation sets local to scope.-->
</correlationSets>
<faultHandlers>
<!-- Fault handlers local to scope. -->
</faultHandlers>
<compensationHandler>
<!-- Compensation handlers local to scope.-->
</compensationHandler>
<terminationHandler>
<!-- Termination handler local to scope. -->
</terminationHandler>
<eventHandlers>
<!-- Event handlers local to scope. -->
</eventHandlers>
activity
</scope>

Each scope has a primary activity. This is similar to the overall process structure, where we have said that a BPEL process also has a primary activity. The primary activity, which is often a <sequence> or <flow>, defines the behavior of a scope for normal execution. Fault handlers and other handlers define the behavior for abnormal execution scenarios.

The primary activity of a scope can be a basic activity such as <invoke>, or it can be a structured activity such as <sequence> or <flow>. Enclosing the <invoke> activity with a scope and defining the fault handlers is equivalent to using inline fault handlers. The inline fault handler shown in the previous article is equal to the following scope:

<scope>
<faultHandlers>
<catch faultName="emp:WrongEmployeeName" >
<!-- Perform an activity -->
</catch>
<catch faultName="emp:TravelNotAllowed"
faultVariable="Description" >
<!-- Perform an activity -->
</catch>
<catchAll>
<!-- Perform an activity -->
</catchAll>
</faultHandlers>
<invoke partnerLink="employeeTravelStatus"
portType="emp:EmployeeTravelStatusPT"
operation="EmployeeTravelStatus"
inputVariable="EmployeeTravelStatusRequest"
outputVariable="EmployeeTravelStatusResponse" >
</invoke>
</scope>

If the primary activity of a scope is a structured activity, it can have many nested activities where the nesting depth is arbitrary. The scope is shared by all nested activities. A scope can also have nested scopes with arbitrary depth.

The variables defined within a scope are only visible within that scope. Fault handlers attached to a scope handle faults of all nested activities of a scope. By default behavior, faults not caught in a scope are rethrown to the enclosing scope. Scopes in which faults have occurred are considered to have ended abnormally, even if a fault handler has caught the fault and not rethrown it.

Similarly as for the <process>, we can define the exitOnStandardFault for a scope as well. If set to no, which is the default, the scope can handle the faults using the corresponding fault handlers. If set to yes, then the scope must exit immediately if a fault occurs (similarly to if it reached an <exit> activity). If we do not set this attribute, it inherits the value from its enclosing <scope> or <process>.

Example

To demonstrate how scopes can be used in BPEL processes, we will rewrite our asynchronous travel process example and introduce three scopes:

  • In the first scope, we will retrieve the employee travel status(RetrieveEmployeeTravelStatus)
  • In the second scope, we will check the flight availability with both airlines(CheckFlightAvailability)
  • In the third scope, we will call back to the client (CallbackClient)

We will also declare those variables that are limited to a scope locally within the scope. This will reduce the number of global variables and make the business process easier to understand. The major benefit of scopes is the capability to define custom fault handlers, which we will also implement. The high-level structure of our travel process will be as follows:

<process ...>
<partnerLinks/>.</partnerLinks>
<variables>...</variables>
<faultHandlers>
<catchAll>...</catchAll>
</faultHandlers>
<sequence>
<!-- Receive the initial request for business travel from client
-->
<receive .../>
<scope name="RetrieveEmployeeTravelStatus">
<variables>...</variables>
<faultHandlers>
<catchAll>...</catchAll>
</faultHandlers>
<sequence>
<!-- Prepare the input for Employee Travel Status Web Service
-->
<!-- Synchronously invoke the Employee Travel Status Web
Service -->
<!-- Prepare the input for AA and DA -->
</sequence>
</scope>
<scope name="CheckFlightAvailability">
<variables>...</variables>
<faultHandlers>
<catchAll>...</catchAll>
</faultHandlers>
<sequence>
<!-- Make a concurrent invocation to AA and DA -->
<flow>
<!-- Async invoke the AA web service and wait for the
callback -->
<!-- Async invoke the DA web service and wait for the
callback -->
</flow>
<!-- Select the best offer and construct the TravelResponse
-->
</sequence>
</scope>
<scope name="CallbackClient">
<faultHandlers>...</faultHandlers>
<!-- Check if the ticket is approved -->
</scope>
</sequence>
</process>

To signal faults to the BPEL process client, we will use the ClientCallbackFault operation on the client partner link, which we defined in the previous article. This operation has a string message, which we will use to describe the fault. In real-world scenarios, the fault message is more complex and includes a fault code and other relevant information.

Let us start with the example. The process declaration and the partner links have not changed:

<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/" >
<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>

The variables section will now define only global variables. These are TravelRequest, FlightDetails, TravelResponse, and TravelFault. We have reduced the number of global variables, but we will have to declare other variables within scopes:

<variables>
<!-- input for this process -->
<variable name="TravelRequest"
messageType="trv:TravelRequestMessage"/>
<!-- input for the Employee Travel Status web service -->
<variable name="FlightDetails"
messageType="aln:FlightTicketRequestMessage"/>
<!-- output from BPEL process -->
<variable name="TravelResponse"
messageType="aln:TravelResponseMessage"/>
<!-- fault to the BPEL client -->
<variable name="TravelFault"
messageType="trv:TravelFaultMessage"/>
</variables>

Next we define the global fault handlers section. Here we use the <catchAll> activity, through which we handle all faults not handled within scopes. We will signal the fault to the BPEL client:

<faultHandlers>
<catchAll>
<sequence>
<!-- Create the TravelFault variable -->
<assign>
<copy>
<from>string('Other fault')</from>
<to variable="TravelFault" part="error" />
</copy>
</assign>
<invoke partnerLink="client"
portType="trv:ClientCallbackPT"
operation="ClientCallbackFault"
inputVariable="TravelFault" />
</sequence>
</catchAll>
</faultHandlers>

The main activity of the BPEL process will still be <sequence>, and we will also specify the <receive> activity to wait for the incoming message from the client:

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

WS-BPEL 2.0 for SOA Composite Applications with IBM WebSphere 7 Define, model, implement, and monitor real-world BPEL 2.0 business processes with SOA-powered BPM for IBM WebSphere 7 with this book and eBook
Published: October 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, see here.)

First scope

Now let's define the first scope for retrieving the employee travel status. Here we will first declare two variables needed for the input and output messages for web service operation invocation:

<scope name="RetrieveEmployeeTravelStatus">
<variables>
<!-- 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" />
</variables>

Next we will define the fault handlers section for this scope. We will use the <catchAll> activity to handle all faults, including Employee web service WSDL faults, communication faults, and other runtime faults. We will signal all faults to the client, although in real-world scenarios we could invoke another web service or perform other recovery operations:

<faultHandlers>
<catchAll>
<sequence>
<!-- Create the TravelFault variable -->
<assign>
<copy>
<from>
string('Unable to retrieve employee travel status')
</from>
<to variable="TravelFault" part="error" />
</copy>
</assign>
<invoke partnerLink="client"
portType="trv:ClientCallbackPT"
operation="ClientCallbackFault"
inputVariable="TravelFault" />
<exit/>
</sequence>
</catchAll>
</faultHandlers>

Next we will start a sequence (which is the main activity of the scope) and prepare the input variable, invoke the Employee web service, and prepare the input for both airlines' web services:

<sequence>
<!-- 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" />
<!-- Prepare the input for AA and DA -->
<assign>
<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>
</sequence>
</scope>

Second scope

In the second scope, we check the flight availability with both airlines' web services. First we declare two variables for storing output from both web service operations:

<scope name="CheckFlightAvailability">
<variables>
<!-- output from American Airlines -->
<variable name="FlightResponseAA"
messageType="aln:TravelResponseMessage"/>
<!-- output from Delta Airlines -->
<variable name="FlightResponseDA"
messageType="aln:TravelResponseMessage"/>
</variables>

Next we define the fault handlers section, where we use the <catchAll> activity, similar to the first scope:

<faultHandlers>
<catchAll>
<sequence>
<!-- Create the TravelFault variable -->
<assign>
<copy>
<from>
string('Unable to invoke airline web service')
</from>
<to variable="TravelFault" part="error" />
</copy>
</assign>
<invoke partnerLink="client"
portType="trv:ClientCallbackPT"
operation="ClientCallbackFault"
inputVariable="TravelFault" />
<exit/>
</sequence>
</catchAll>
</faultHandlers>

The main activity of the second scope will be a <sequence>, in which we will first concurrently invoke both airlines' web services using a <flow> activity and then select the best offer using an <if> activity:

<sequence>
<!-- Make a concurrent invocation to AA and 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>
<sequence>
<!-- Async invoke of the DA web service and wait for the
callback -->
<invoke partnerLink="DeltaAirlines"
portType="aln:FlightAvailabilityPT"
operation="FlightAvailability"
inputVariable="FlightDetails" />
<receive partnerLink="DeltaAirlines"
portType="aln:FlightCallbackPT"
operation="FlightTicketCallback"
variable="FlightResponseDA" />
</sequence>
</flow>
<!-- Select the best offer and construct the TravelResponse -->
<if>
<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>
</sequence>
</scope>

Third scope

In the third scope. we call back to the BPEL client. For this scope we do not need additional variables. However, we define a fault handler to handle the TicketNotApproved fault. Therefore, we explicitly specify the fault name and the fault variable. Note that we do not use the <catchAll> activity in this fault handlers section, so all unhandled faults will be rethrown to the main process fault handler:

<scope name="CallbackClient">
<faultHandlers>
<catch faultName="trv:TicketNotApproved"
faultVariable="TravelFault">
<!-- Make a callback to the client -->
<invoke partnerLink="client"
portType="trv:ClientCallbackPT"
operation="ClientCallbackFault"
inputVariable="TravelFault" />
</catch>
</faultHandlers>

The main activity of this scope is the <if> activity, where we check if the flight ticket has been approved:

<!-- Check if the ticket is approved -->
<if>
<condition>
$TravelResponse.confirmationData/aln:Approved='true'
</ condition>
<!-- Make a callback to the client -->
<invoke partnerLink="client"
portType="trv:ClientCallbackPT"
operation="ClientCallback"
inputVariable="TravelResponse" />
<else>
<sequence>
<!-- Create the TravelFault variable with fault
description -->
<assign>
<copy>
<from>string('Ticket not approved')</from>
<to variable="TravelFault" part="error" />
</copy>
</assign>
<!-- Throw fault -->
<throw faultName="trv:TicketNotApproved"
faultVariable="TravelFault" />
</sequence>
</else>
</if>
</scope>
</sequence>
</process>

Isolated scopes

For each scope, we can specify whether we require concurrency control over shared variables, partner links, and dependency links. We will need such control if, in our scenario, more than one instance uses shared variables concurrently. This can occur, for example, if we use a parallel <forEach> loop, which starts several parallel branches of the same <scope>.

Scopes that require concurrency control are called isolated scopes. In isolated scopes, it is ensured that the results of the scope will be equal, if all conflicting activities on all shared variables and partner links are done in any possible sequence. This guarantees that there will be no conflicting situations if several concurrent scopes access the same set of shared variables. Conflicting operations are, in this case, all read/write and write-only activities, such as assignments, incoming messages stored in variables, and so on. The semantics of isolated scopes are similar to the serializable transaction isolation level.

We denote a scope as isolated using the optional attribute isolated, and setting it to yes. The default value of this attribute is no. Isolated scopes must not contain other isolated scopes (but may contain scopes that are not marked as isolated). The fault handlers (and other handlers) associated with the scope also share the isolation. The following code excerpt shows how to declare a scope as isolated:

<scope isolated="yes" >
</scope>

Summary

In the above article we covered:

  • Examples
  • Isolated scopes

Further resources on this subject:


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

About the Author :


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


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

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

Oracle SOA Suite 11g R1 Developer's Guide
Oracle SOA Suite 11g R1 Developer's Guide

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

IBM Lotus Notes 8.5 User Guide
IBM Lotus Notes 8.5 User Guide

IBM Lotus Notes and Domino 8.5.1
IBM Lotus Notes and Domino 8.5.1

SOA and WS-BPEL
SOA and WS-BPEL

IBM InfoSphere Replication Server and Data   Event Publisher
IBM InfoSphere Replication Server and Data Event Publisher


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
2
4
r
a
S
P
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