7 min read

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 or ). 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 , , , , , , , and locally for the scope. All are optional:


























activity


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 or , 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 , or it can be a structured activity such as or . Enclosing the 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:






faultVariable=”Description” >






portType=”emp:EmployeeTravelStatusPT”
operation=”EmployeeTravelStatus”
inputVariable=”EmployeeTravelStatusRequest”
outputVariable=”EmployeeTravelStatusResponse” >


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 , 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 activity). If we do not set this attribute, it inherits the value from its enclosing or .

How scopes can be used in BPEL processes

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:


.





–>







–>
Service –>











callback –>
callback –>

–>








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:

targetNamespace=”http://packtpub.com/bpel/travel/”

>

partnerLinkType=”trv:travelLT”
myRole=”travelService”
partnerRole=”travelServiceCustomer”/>
partnerLinkType=”emp:employeeLT”
partnerRole=”employeeTravelStatusService”/>
partnerLinkType=”aln:flightLT”
myRole=”airlineCustomer”
partnerRole=”airlineService”/>
partnerLinkType=”aln:flightLT”
myRole=”airlineCustomer”
partnerRole=”airlineService”/>


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:



messageType=”trv:TravelRequestMessage”/>

messageType=”aln:FlightTicketRequestMessage”/>

messageType=”aln:TravelResponseMessage”/>

messageType=”trv:TravelFaultMessage”/>


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







string(‘Other fault’)



portType=”trv:ClientCallbackPT”
operation=”ClientCallbackFault”
inputVariable=”TravelFault” />



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



portType=”trv:TravelApprovalPT”
operation=”TravelApproval”
variable=”TravelRequest”
createInstance=”yes” />


Subscribe to the weekly Packt Hub newsletter

* indicates required

LEAVE A REPLY

Please enter your comment!
Please enter your name here