Advanced BPEL

Variable initialization

When a variable is declared in a BPEL process, it has no value until one is assigned to it. From within a Java Snippet, extra care must be taken as the variable will appear as a null-valued reference when accessed before assignment. If you need to assign a value to a variable for the 1st time in a Snippet, create an instance of the typed object. You can use the BOFactory to create a BO.

Scope

WBI-SF, the predecessor to WPS, only supported a subset of BPEL. One of the items that was noticeably missing was the concept of Scope. Variables have a strong relationship to Scope. By default, all variables in BPEL have Global scope. This means that they can be used and accessed throughout the lifetime of the process anywhere in the process. This sounds good until you realize that variables may transiently hold large amounts of data and you don't want to have to worry about managing the size of that data throughout the whole process. In addition, a variable used in one section of your process may have no use or effect in others and you don't want to clutter the whole solution with irrelevant variables floating around.

Scope assists with these problems by allowing you to define a variable that exists only within a scope. This is similar to local variables in programming terms. Creating a variable in a scope means that it can only be accessed by activities in the same scope or lower.

BPEL - Java Mapping

The simple variable types in BPEL map to XML Schema types which map to Java. The following are the more interesting:


The format for the date/time Strings can be read about at the XSD page.

Variable Properties

Consider a data structure called Order that has three fields in it ...


Consider a second data structure called Purchase that has three fields in it ...


Both data structures have a logical field that is used to hold the identity of a customer. In the Order data structure, it is the field called customerId. In the Purchase data structure, it is the field called custNum. In both cases, this field is the logical identity of the customer but in each case, it is named differently (presumably by the different data designers). If we write a BPEL process that uses either Order or Purchase and wishes to refer to the identity of the customer, the process is going to be tightly bound to the name of the field in the data structure.

BPEL provides a concept that they call variable properties. A property is a named entity with associated data type. So a property could be created called customerIdentity with data type String. In a BPEL process, instead of referring to a specific named field in a variable, the property name can be used instead. In order for this to work, there must be a mapping or alias that relates the named property to the name of the field within the data structure.

Logically we can then create the following (note that this is not BPEL syntax):

Define: propertyName = "customerIdentity", type="String"

we can then create aliases:

Define: alias propertyName = "customerIdentity", data="Order->customerId"

Define: alias propertyName = "customerIdentity", data="Purchase->custNum"

Once these are defined, we can then get the customer identity by:

getVariableProperty("Order", "customerIdentity") will return Order->customerId

getVariableProperty("Purchase", "customerIdentity") will return Purchase->custNum

Endpoint References

In BPEL, a partner link is a place holder for both how the process appears to others and how the BPEL process sees partners that it may call. Associated with the logical partner link are the actual endpoints or bindings that, when used, serve as the actual endpoints for the service calls. These endpoints can be both queried and set within a BPEL process. There are two different types of endpoints. These are the endpoints that the process itself exposes or appears as (MY ROLE) and the endpoints at which the partners exist (PARTNER ROLE). Both can be queried but only the partner role endpoints may be set. It doesn't make any sense to dynamically change the location at which the process is actually listening.

Within either a JavaSnippet or an Assign activity, the endpoint values may be obtained or set.

|| |Name|Description| |Service|The name of the referenced service.| |Address|The address of the endpoint. This may be a logical value as opposed to a TCP/IP address or hostname.| |PortType|The WSDL port type being accessed. Think of it like the name of an interface in Java.| |Port|A binding to the endpoint at the target service.|

The Address object contains a field called value. This can be set to the target of the Partner Link. For a component in the same module, this can be <ModuleName>/<ComponentName>.

BPEL Endpoint Reference variable type

A BPEL variable can be used to hold an endpoint reference. The data type used to contain such an entity is the ServiceRefType. This is described a series of XSD schema files that can also be used as Business Objects. The XSDs that described these data types can be automatically generated. By opening the project's dependencies and select the WS-Addressing Schema Files from the Predefined Resources section, a set of additional XSDs are added into the project.

The two primary ones of interest are:

If we create a BPEL variable called 'myRef' and make it of type ServiceRefType, then we can use a BPEL Assign activity to set a partner reference to the variable.

JavaSnippet access

getServiceRefFromPartnerLink

commonj.sdo.DataObject getServiceRefFromPartnerLink( String partnerLinkName, int role );

This method is used to retrieve the Service destination at the end of the named partner link. The role value must be one of:

What is returned is a DataObject that contains an EndpointReference object retrieved with the name "EndpointReference".

Example:

Here is a java fragment retrieving a PartnerLink binding called RequestReply

DataObject myDo = getServiceRefFromPartnerLink("RequestReply", PARTNER_LINK_PARTNER_ROLE); EndpointReference ref = (EndpointReference)myDo.get("EndpointReference"); System.out.println("Address: " + ref.getAddress()); System.out.println("Port: " + ref.getPort()); System.out.println("Service: " + ref.getService().toString());

If the wired target is an Import of a Web Service, then the values are that of a Web Service. If the wired target is any other SCA component, then the only meaningful value is the Address field which contains the module and component which is the target. For example Module/Component.

Query Properties

Consider a BPEL process template. This is used to instantiate process instances. Now imagine that you want to find a particular instance of a process. Maybe the process model handles orders and when a customer submits an on-line order, an instance of the process gets generated and the customer is given an orderid. How do you find the specific process instance that has a specific order-id?

The answer to these questions is through the capability called query properties. A Query Property is basically a property (or attribute) that can be associated with an instance of a process. While the process is running, a query can be executed to return a list of processes where the property has a specific value or, conversely given a process, to retrieve the current value of the property.

As multiple BPEL process instances execute, what differentiates one from another is the state of data maintained within the context of that process. The value of the query property is mapped from the value of a BPEL variable.

During the design of a BPEL process, one or more query properties can be created. They are created in the properties view in WID associated with variables. When the BPEL process executes, whatever is the current value of the variable in the Process will be the current value of the query property associated with the process instance.

Implementation

The implementation of query properties appears to be through the creation of additional tables in the BPEDB database. The tables identified as being associated with query properties are:

QUERYABLE_VARIABLE_INSTANCE_T

Performance

When a variable's value changes within the BPEL process and that variable is associated with a query property, then the value must be updated in the query properties table. This means an extra SQL update for each modification of a query property associated variable.

Activities

Activities described:

Inline Human Tasks

Invoke

JavaSnippet

Inline Human Tasks

The majority of Human Task information can be found in the Human Task section. This section covers the BPEL specific in-line Human Task.

In-line Human Tasks are IBM additions to the BPEL implementation that create Tasks in the Human Task manager within the context of the BPEL process. This allows additional or overriding information to be supplied to the human task.

Previous task owners

In a BPEL process, an in-line Human Task can be performed and then in subsequent BPEL activities, the owner of that task may wish to be known. The previous owner of the task can be retrieved within the process using the following recipe.

In a Java Snippet (psuedo code):

ActivityInstanceData aid = bfm.getActivityInstance( PIID piid, java.lang.String activityTemplateName); TKIID tkid = aid.getTaskID(); Task task = htm.getTask(TKIID tkiid); String owner = task.getOwner();

where:

bfm = The handle to the Business Flow Manager

htm = The handle to the Human Task Manager

Invoke

Arguably, the Invoke Activity is the single most important construct in BPEL. Invoke is used to invoke the services of some other component outside of the BPEL process. Within nothing more than a set of Invoke activities, we can choreograph a set of services together.

Expiration

IBM has extended the BPEL specification with an Expiration option. Understand that this is not standard BPEL. The semantics of Expiration is that for asynchronously implemented service calls, we can abandon the wait for a response. This also means that expiration does not apply to short running process definitions. This basically means that if we send a request to a target service over JMS and wait for a response, we can timeout after a period of time before the response comes back. The expiration can be supplied as either an absolute date/time (an expiration) or a relative time to wait (a duration) specified in seconds. If no response is received before the expiration triggers, a timeout fault is automatically raised.

note: Experimentation and observation seems to show that the expiration is the minimum amount of time to wait, don't expect the process to instantly see the fault after the expiration period, it can possibly take some time for the system to realize that it shouldn't wait any more.

The timeout value for the expiration can be specified as either:

Java code

Xpath

An absolute value (using a CRON calendar)

A relative value (using a Simple calendar)

Through either Java code or XPath, access to the variables in the process can be achieved and thus the expiration can be a dynamic value based on a variable's value.

The following image illustrates setting the Expiration values.

When a Timeout fires, the Timeout fault can be caught in a fault handler:

If you want to add an expiration timeout in a short running process definition, consider placing a mediation flow component between the reference terminal in the BPEL SCA component and the SCA Import to the target service. In the mediation flow component, have the interface and reference both defined as the same interface type which is that of both the BPEL process reference and the SCA Import.

In the mediation flow component, wire both the request and responses directly from their inputs to their outputs. In the Request callout node, set the a timeout value to be the required timeout and set the invocation style to be Async.

If no response has arrived within the timeout interval, the Response flow will fire on the fail terminal which can be used to signal a failure to the original caller.

JavaSnippet

By and large BPEL allows you to perform all the tasks you might want to achieve for process choreography. IBM has extended BPEL with the concept of Snippets which can be expressed in the Java programming language. Within the Java Snippet you have access to all the variables in the process and can both set and get their values. The snippet can also be coded in the Visual Snippet language.

Working with variables

Variables inside the BPEL Java Snippet are really Business Objects which are actually SDO DataObjects or they are boxed simple types (eg. Integer()). The recipe to create a new DataObject is documented in the SCA section of the Wiki.

Methods available in a Java Snippet

A series of method calls are also available to you. These are:

getServiceRefFromPartnerLink

DataObject getServiceRefFromPartnerLink(String partnerLinkName, int role);

See Endpoint References for information.

setServiceRefToPartnerLink

void setServiceRefToPartnerLink(String partnerLinkName, DataObject serviceRef);

getVariableProperty

These methods either specify or return the value of a process variable's property. If either the property or the variable do not exist, a StandardFaultException of kind "selection failure" is thrown. If the value is not compatible to the type of the property, a StandardFaultException of kind "mismatch assignment failure" is thrown.

setVariableProperty

These methods either specify or return the value of a process variable's property. If either the property or the variable do not exist, a StandardFaultException of kind "selection failure" is thrown. If the value is not compatible to the type of the property, a StandardFaultException of kind "mismatch assignment failure" is thrown.

getCorrelationSetProperty

This method can be used to retrieve the properties of correlation sets that are declared at the process level. If either the property with name propertyName or the correlation set with name correlationSetName do not exist, a StandardFaultException of kind "selection failure" is thrown.

getProcessCustomProperty

String getProcessCustomProperty(String propertyName)

Use these methods to access or define custom properties at the process level.

setProcessCustomProperty

void setProcessCustomProperty(String propertyName, String propertyValue);

Use these methods to access or define custom properties at the process level.

getActivityCustomProperty

Use these methods to access or define custom properties at the activity level. If the activity does not exist, or activityName does not uniquely qualify an activity, a StandardFaultException of kind "selection failure" is thrown. If the value exceeds 254 bytes, an InvalidLengthException is thrown.

setActivityCustomProperty

Use these methods to access or define custom properties at the activity level. If the activity does not exist, or activityName does not uniquely qualify an activity, a StandardFaultException of kind "selection failure" is thrown. If the value exceeds 254 bytes, an InvalidLengthException is thrown.

getLinkStatus

This method can be used in join conditions to access the state of the incoming links.

activityInstance

Use this method to return the current activity or a named activity as an object in order to access its content. The object type returned is an ActivityInstanceData. For example, assume that a preceding activity in a BPEL process was an in-line Human Task called "MyTask". Assume that it was previously executed. To obtain the user that owned that task the following code could be used:

ActivityInstanceData ai = activityInstance("MyTask"); String owner = ai.getOwner(); System.out.println("Owner = " + owner);

processInstance

ProcessInstanceData processInstance();

This method retrieves the PIID object (ProcessInstanceData) for the callers process. This object holds a wealth of information relating to the current instance of the process. Some possible uses include:

Getting a unique name for the process. The getID() method returns a PIID. This can then have its toString() method called to retrieve a string representation of the process id that is unique to this instance. This could possibly be used as a correlation value or other unique id string.

raiseFault

Use this method to raise a fault in the surrounding process.

forceRollback

Use this to cause the compensation of the microflow. This method will not work with long running processes.

getCurrentFaultAsException

com.ibm.bpe.api.BpelException getCurrentFaultAsException()

Retrieve the current fault in a fault handler as a Java object.

Standard Functions

Arrays

Converter

Date

current date and time

Returns a java.util.Date that represents the current time.

format locale date to string using pattern

Inputs

java.util.Date – The date to be formatted

String – The pattern to be applied to the date. The pattern is a pattern string as supplied to java.text.SimpleDateFormat.

Outputs

String – A string representation of the formatted date

Description

Returns a string representation of an input date that has been formatted to a pattern.

Custom Properties

References

BPEL Process Migration

References

No Comments
Back to top