|
Page Edited :
ODExSITE :
BPEL Extensions
BPEL Extensions has been edited by Assaf Arkin (Nov 15, 2007). Content:ODE extends the WS-BPEL in areas that aren't covered by the spec. This page details these extensions. Implicit CorrelationsIntroductionBPEL process instances are stateful — therefore, a client interacting with the BPEL engine must identify the particular instance with which it intends to interact in all of its communications. The BPEL specification defines a mechanism — correlation — which allows the process designer to specify which parts of an incoming message (i.e. a message going from a client to the BPEL server) should be used to identify the target process instance. Correlation is a powerful mechanism — however it is a bit complicated and relies on "in-band" message data to associate a messages with a process instance. To keep simple cases simple, ODE provides an alternative correlation mechanism — implicit correlation — that automatically handles correlation through "out-of-band" session identifiers. The mechanism is simple: a unique session identifier is associated with every every partner link instance. When a message is sent on a partner link, the session identifier is sent along with the message. The recipient is then able to use the received session identifier in subsequent communications with the process instance. Messages received by the BPEL engine that have a session identifier are routed to the correct instance (and partner link) by that session identifer. There are two major use cases for the implicit correlation mechanism requiring different levels of familiarity with the mechanism's details: process to process and process to service interactions. The former case deals with situations where the ODE BPEL process instance is communicating with another ODE process instance. The latter deals with situations where a ODE BPEL process instance is communicating with an external (non-ODE) service. Process to Process Interaction Use CaseWhen an ODE process needs to communicate with other ODE processes, using implicit correlations is quite simple. Simply omit the <correlations> element from the <receive>, <pick>, and <invoke> activities. The following is an example showing one process (processA) starting another (processB) and then being called back:
In the above example, ODE will use the implicit correlation mechanism because no explicit correlations are specified. Communication between the two processes will reach the correct instance as long as the same partner link is used. For a complete example check MagicSession Process to Service Interaction Use CaseSee the Stateful Exchange Protocol. Activity Failure and RecoveryThere are several types of error conditions. In this document we introduce a class of error condition called failures, distinct from faults, and describe how failures are caught and handled by the process engine. A service returns a fault in response to a request it cannot process. A process may also raise a fault internally when it encounters a terminal error condition, e.g. a faulty _expression_ or false join condition. In addition, processes may raise faults in order to terminate normal processing. In contrast, failures are non-terminal error conditions that do not affect the normal flow of the process. We keep the process definition simple and straightforward by delegating failure handling to the process engine and administrator. For example, when the process is unable to perform DNS resolution to determine the service endpoint, it generates a failure. An administrator can fix the DNS server and tell the process engine to retry the activity. Had the DNS error been reported as a fault, the process would either terminate or require complex fault handling and recovery logic to proceed past this point of failure. In short, failures shields the process from common, non-terminal error conditions while retaining simple and straightforward process definitions that do not need to account for these error conditions. From Failure to RecoveryCurrently, the Invoke activity is the only activity that supports failure handling and recovery. The mechanism is identical for all other activities that may support failure handling and recovery in the future. In case of the Invoke activity, a failure condition is triggered by the integration layer, in lieu of a response or fault message. The Invoke activity consults its failure handling policy (specified here) and decides how to respond. Set faultOnFailure to yes, if you want the activity to throw a fault on failure. All other failure handling settings are ignored. The activity will throw the activityFailure fault. The activityFailure fault is a standard fault, so you can use the exitOnStandardFault attribute to control whether the process exits immediately, or throws a fault in the enclosing scope. Set retryFor to a positive integer if you want the activity to attempt self-recovery and retry up to that number of times. Set retryDelay to a reasonable time delay (specified in seconds) between retries. For example, if you set retryFor=2, retryDelay=30, the activity will retry after 30 and 60 seconds, for a total of three attempts, before entering activity recovery mode. If the activity retries and succeeds, it will complete successfully as if no failure occurred. Of course, the activity may retry and fault, e.g. if the invoked service returns a fault. If the activity has exhausted all retry attempts, it enters activity recovery mode. By default retryFor is zero, and the activity enters recovery mode after the first failure. When in recovery mode, you can recover the activity in one of three ways:
Specifying Failure BehaviorUse the failureHandling extensibility element defined in the namespace http://ode.apache.org/activityRecovery <ext:failureHandling xmlns:ext="http://ode.apache.org/activityRecovery"> <ext:faultOnFailure> _boolean_ </ext:faultOnFailure> <ext:retryFor> _integer_ </ext:retryFor> <ext:retryDelay> _integer_ </ext:retryDelay> </ext:failureHandling> The faultOnFailure, retryFor and retryDelay elements are optional. The default values are false for faultOnFailure, and zero for retryFor and retryDelay. An activity that does not specify failure handling using this extensibility element, inherits the failure handling policy of its parent activity, recursively up to the top-level activity of the process. You can useinheritence to specify the failure handling policy of a set of activities, or all activities in the process, using a single failureHandling extensibility element. Note that due to this behavior, if activity S specifies failure handling with the values retryFor=2, retryDelay=60, and has a child activity R that specifies failure handling with the values retryFor=3, the retryDelay value for the child activity R is 0, and not 60. Using the failureHandling element without specifying one of its value elements will apply the default value for that element. ExamplesA simple invoke with the ext:failureHandling extension: <bpel:invoke inputVariable="myRequest" operation="foo" outputVariable="aResponse" partnerLink="myPartner" portType="spt:SomePortType"> <ext:failureHandling xmlns:ext="http://ode.apache.org/activityRecovery"> <ext:faultOnFailure>false</ext:faultOnFailure> <ext:retryFor>2</ext:retryFor> <ext:retryDelay>60</ext:retryDelay> </ext:failureHandling> </bpel:invoke> And a sequence activity that converts failures into faults: <bpel:sequence> <ext:failureHandling xmlns:ext="http://ode.apache.org/activityRecovery"> <ext:faultOnFailure>true</ext:faultOnFailure> </ext:failureHandling> ... <bpel:invoke inputVariable="myRequest" operation="foo" outputVariable="aResponse" partnerLink="myPartner" portType="spt:SomePortType"> <bpel:catchAll> ... </bpel:catchAll> </bpel:invoke> </bpel:sequence> Process Instance ManagementThe process instance management provides the following information:
Use the recoverActivity operation to perform a recovery action on an activity in recovery mode. The operation requires the process instance ID, the activity instance ID and the recovery action to perform (one of retry, fault or cancel). You can also determine when failure or recovery occurred for a given activity instance from the execution log. XPathApache ODE extends the default XPath coverage provided by the WS-BPEL XPath 2.0To use XPath 2.0 in your processes just use the following queryLanguage and expressionLanguage attributes: queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0" expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0" If you want support at the process just add these attributes to your root process element. If you want to stick with XPath 1.0 but want XPath 2.0 support for a specific assignment you can also define these attributes on an assign element. Extension FunctionsAll extension fucntions are defined in the ODE extension namespace: http://www.apache.org/ode/type/extension splitToElementsIt's impossible to split a given string into a sequence of elements using assignments. The only possible alternative is XSL which is a lot of complexity for a very simple usage pattern. The ode:splitToElements function splits a given string (that can be a variable reference) into several elements by using a specific separators. Here is an example: <assign> <from>ode:splitToElements($authorizeMessage.credential/userList, ',', 'user')</from> <to>$authorizedUsers</to> </assign> If the source element contains a list like "joe, paul, fred" the target variable will be assigned the sequence of elements: <user>joe</user> <user>paul</user> <user>fred</user> Alternatively this function can take a fourth parameter that would be the namespace of the elements used to wrap the split strings: ode:splitToElements(stringToSplit, separator, targetElement, targetNamespace) External VariablesDeclaring External Variables in the Process Definition
Syntax: <scope> <variables xmlns:evar=" http://www.apache.org/ode/extensions/externalVariables"> <variable name="ext-var-name" element="ext-var-type" evar:ext-var-id="ext-var-id"> <evar:key-map key="key-id">* <_expression_>key-_expression_</_expression_> </evar:key-map> </variable> </variables> </scope> External variables are declared in the <variables> section of the <scope> element, just like normal variables. However, unlike regular variables, external variables must specify the additional evar:ext-var-id attribute. This attribute identifies the variable as an external variable and links the external variable's declaration to the external variable's configuration in the deployment descriptor. In addition to this attribute, an external variable may also define a set of key mappings by nesting evar:key-map elements within the declaration. The key mappings are a collection of name-_expression_ pairs that is used to create a composite key (identity) for the external variable. This composite key is used to retrieve the correct "instance" of the variable from the underlying storage. The key mappings are BPEL expressions ( i.e. XPath expressions) that are evaluated once, at the time that the scope is instantiated. Therefore, the "identity" of an external variable is determined during scope creation, and cannot be changed by the process (for qualifications see Incomplete Keys below). Finally, any external variables must be of an "element" type, with a schema conforming to the requirements of the underlying storage mechanism. Consider the following example: process.bpel . . . <scope> <variables> <variable name="customer" element="myns:CustomerElement" evar:ext-var-id="customer1" > <evar:key-map key="customer-id"> <_expression_>$order/customerid</_expression_> </evar:key-map> </variables> </scope> . . . In the above, the "customer" variable is an external variable. The key for the external variable is derived from the value of the customerid element in the "order" variable. Note that the "order" variable must be declared in a scope above the scope declaring the "customer" external variable, otherwise it would not be possible to resolve the identify of the "customer" variable. In this scenario, the external variable can be "read" even if it was never assigned to in the process. Incomplete KeysIt is not required that the full identity of the external variable be resolved at scope creation. For example, an external variable may correspond to a database row where the identity is generated by the database during an insert operation. In such a scenario the key mapping can be omitted, and the identity of the external variable will be unknown until the variable is assigned to. Any attempt to access the variable before the first assignment will result in an uninitialized variable fault. In general it is possible to specify external variables where some portions of the identity are determined using the key mappings and some using some other (implementation-specific) mechanism. In any case, if when the variable is read, the key is incomplete an uninitialized variable fault will result. RESTful BPELInvokeThe RESTfulvariant of the invoke activity replaces the attributes partnerLink/operation with resource and method. The method attribute identifies the HTTP method. All HTTP methods are supported, although this spec is only concerned with GET, POST, PUT and DELETE. The resource attribute identifies a BPELvariable of a simple type (xsd:uri, xsd:string, etc) used as the URL of the actual resource. The resource element can be used instead of the resource attribute to calculate the URL using an _expression_. In addition to the above, the invoke activity adds a way to map values to/from HTTP headers, using a syntax similar to that for mapping message parts, but specifying the corresponding HTTP header instead. Headers mapped by the process override default values, and some headers have special handling. The implementation shields the invoke activity from some of the details of the HTTP protocol, specifically:
This example uses the myPost variable to create a new blog post, store the response in the newPost variable, and the location of the new post in the variable newPostUrl: invoke resource=createPostsUrl method=post input=myPost output=newPost from header=location to=newPostUrl And to update the post: invoke resource=newPostUrl method=put input=updatedPost XPath functionsThe use or URLs requires the ability to combine URLs with two new XPath functions: combineUrl(base, relative)Takes the relative URL and combines it with the base URL to return a new absolute URL. If the relative parameter is an absolute URL, returns it instead. composeUrl(template, [name, value]*)composeUrl(template, pairs)Expands the template URL by substituting place holders in the template, for example, ('/order/{id}', 'id', 5) returns '/order/5'. Substitute values are either name/value pairs passed as separate parameters, or a node-set returning elements with name mapping to value. The functions applies proper encoding to the mapped values, and with incomplete mapping may return a new URL template. |
Unsubscribe or edit your notifications preferences
