12 Using Fault Handling in a BPEL Process
This chapter includes the following sections:
12.1 Introduction to a Fault Handler
Fault handlers define how the BPEL process service component responds when target services return data other than what is normally expected (for example, returning an error message instead of a number). An example of a fault handler is where the web service normally returns a credit rating number, but instead returns a negative credit message.
Figure 12-1 provides an example of how a fault handler sets a credit rating variable to -1000
.
The code segment in the following example defines the fault handler for this operation in the BPEL file:
<faultHandlers> <catch faultName="services:NegativeCredit" faultVariable="crError"> <assign name="crin"> <copy> <from expression="-1000"> </from> <to variable="input" part="payload" query="/autoloan:loanApplication/autoloan:creditRating"/> </copy> </assign> </catch> </faultHandlers>
The faultHandlers
tag contains the fault handling code. Within the fault handler is a catch activity, which defines the fault name and variable, and the copy instruction that sets the creditRating
variable to -1000
.
When you select web services for the BPEL process service component, determine the possible faults that may be returned and set up a fault handler for each one.
12.2 Introduction to BPEL Standard Faults
This section identifies the standard faults for BPEL 1.1 and BPEL 2.0.
12.2.1 BPEL 1.1 Standard Faults
This section identifies the standard faults for BPEL 1.1. Unless otherwise noted below, the Business Process Execution Language for Web Services Specification defines the following standard faults in the namespace of http://schemas.xmlsoap.org/ws/2003/03/business-process/
:
-
bindingFault
(BPEL extension fault defined inhttp://schemas.oracle.com/bpel/extension
) -
conflictingReceive
-
conflictingRequest
-
correlationViolation
-
forcedTermination
-
invalidReply
-
joinFailure
-
mismatchedAssignmentFailure
-
remoteFault
(BPEL extension fault defined inhttp://schemas.oracle.com/bpel/extension
) -
repeatedCompensation
-
selectionFailure
-
uninitializedVariable
-
assertFailure
-
coordinationFault
-
entityInternalNestedError
-
maxLoopCountExceeded
-
owsmPolicyFault
-
rollback
-
timeout
Standard faults are defined as follows:
-
Typeless, meaning they do not have associated
messageTypes
-
Not associated with any Web Services Description Language (WSDL) message
-
Caught without a fault variable:
<catch faultName="bpws:selectionFailure">
12.2.2 BPEL 2.0 Standard Faults
The following list specifies the standard faults defined within the WS-BPEL specification. All standard fault names are qualified with the standard WS-BPEL namespace.
-
ambiguousReceive
-
completionConditionFailure
-
conflictingReceive
-
conflictingRequest
-
correlationViolation
-
invalidBranchCondition
-
invalidExpressionValue
-
invalidVariables
-
joinFailure
-
mismatchedAssignmentFailure
-
missingReply
-
missingRequest
-
scopeInitializationFailure
-
selectionFailure
-
subLanguageExecutionFault
-
uninitializedPartnerRole
-
uninitializedVariable
-
unsupportedReference
-
xsltInvalidSource
-
xsltStylesheetNotFound
12.2.2.1 Fault Handling Order of Precedence in BPEL 2.0
In BPEL 2.0, the order of precedence for catching faults thrown without associated data is as follows:
-
If there is a catch activity with a matching
faultName
value that does not specify afaultVariable
attribute, the fault is sent to the identified catch activity. -
Otherwise, if there is a catchAll activity, the fault is sent to the catchAll fault handler.
-
Otherwise, the fault is processed by the default fault handler.
In BPEL 2.0, the order of precedence for catching faults thrown with associated data is as follows:
-
If there is a catch activity with a matching
faultName
value that does not specify afaultVariable
attribute, the fault is sent to the identified catch activity. -
If the fault data is a WSDL message type in which the following exists:
-
The message contains a single part defined by an element.
-
A catch activity with a matching
faultName
value that has afaultVariable
whose associatedfaultElement
QName matches the QName of the runtime element data of the single WSDL message part.
Then, the fault is sent to the identified catch activity with the
faultVariable
initialized to the value in the single part's element. -
-
Otherwise, if there is a catch activity with a matching
faultName
value that does not specify afaultVariable
attribute, the fault is sent to the identified catch activity. In this case, the fault value is not available from within the fault handler, but is available to the rethrow activity. -
Otherwise, if there is a catch construct without a
faultName
attribute that has afaultVariable
whose type matches the type of the runtime fault data, then the fault is sent to the identified catch activity. -
Otherwise, if the fault data is a WSDL message type in which the message contains a single part defined by an element and there exists a catch activity without a
faultName
attribute that has afaultVariable
whose associatedfaultElement
QName matches the QName of the runtime element data of the single WSDL message part, the fault is sent to the identified catch activity with thefaultVariable
initialized to the value in the single part's element. -
Otherwise, if there is a catchAll activity, the fault is sent to the catchAll fault handler.
-
Otherwise, the fault is handled by the default fault handler.
12.3 Introduction to the Business and Runtime Fault Categories of BPEL Faults
A BPEL fault has a fault name called a Qname
(name qualified with a namespace) and a possible messageType
. There are two categories of BPEL faults:
-
Business faults
-
Runtime faults
12.3.1 Business Faults
Business faults are application-specific faults that are generated when there is a problem with the information being processed (for example, when a social security number is not found in the database). A business fault occurs when an application executes a throw activity or when an invoke activity receives a fault as a response. The fault name of a business fault is specified by the BPEL process service component. The messageType
, if applicable, is defined in the WSDL file. A business fault can be caught with a faultHandler
using the faultName
and a faultVariable
.
<catch faultName="ns1:faultName" faultVariable="varName">
12.3.2 Runtime Faults
Runtime faults are the result of problems within the running of the BPEL process service component or web service (for example, data cannot be copied properly because the variable name is incorrect). These faults are not user-defined, and are thrown by the system. They are generated for a variety of reasons, including the following:
-
The process tries to use a value incorrectly.
-
A logic error occurs (such as an endless loop).
-
A Simple Object Access Protocol (SOAP) fault occurs in a SOAP call.
-
An exception is thrown by the server.
Several runtime faults are automatically provided. These faults are included in the http://schemas.oracle.com/bpel/extension
namespace. These faults are associated with the messageType
RuntimeFaultMessage
. The WSDL file shown in the following example defines the messageType
:
<?xml version="1.0" encoding="UTF-8" ?> <definitions name="RuntimeFault" targetNamespace="http://schemas.oracle.com/bpel/extension" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/"> <message name="RuntimeFaultMessage"> <part name="code" type="xsd:string" /> <part name="summary" type="xsd:string" /> <part name="detail" type="xsd:string" /> </message> </definitions>
If a faultVariable
(of messageType
RuntimeFaultMessage
) is used when catching the fault, the fault code can be queried from the faultVariable
, along with the fault summary and detail.
12.3.2.1 bindingFault
A bindingFault
is thrown inside an activity if the preparation of the invocation fails. For example, the WSDL of the process fails to load. A bindingFault
is not retriable. This type of fault usually must be fixed by human intervention.
12.3.2.2 remoteFault
A remoteFault
is also thrown inside an activity. It is thrown because the invocation fails. For example, a SOAP fault is returned by the remote service.
12.3.2.3 replayFault
A replayFault
replays the activity inside a scope. At any point inside a scope, this fault is migrated up to the scope. These faults are not populated into a common fault, but are an indication to BPEL to re-execute the scope. The server then re-executes the scope from the beginning.
12.3.3 How to Add and Propagate Fault Handling in a Synchronous BPEL Process
This section describes how to add and propagate fault handling in a synchronous BPEL process. During the design, you perform the following tasks:
-
Modify the existing schema and WSDL files to include fault element, fault message, and fault operation details.
-
Add fault handling to the BPEL process (specifically, a catch activity).
-
Create a fault variable with the fault message type you specified in the WSDL file.
-
Add assign and reply activities with additional fault handling details.
12.3.3.4 Add an Assign Activity to the Catch Activity Branch
To add an assign activity to the catch activity branch:
12.4 Handling Faults with the Fault Management Framework
Oracle SOA Suite provides a generic fault management framework for handling faults in BPEL processes. If a fault occurs during runtime in an invoke activity in a process, the framework catches the fault and performs a user-specified action defined in a fault policy file associated with the composite or component. Fault policies are applicable to the faults that result from the invoke activity. Faults can occur because of preassertion, postassertion, invocation, or actual business failures in the target service.
If a fault results in a condition in which human intervention is the prescribed action, you perform recovery actions from Oracle Enterprise Manager Fusion Middleware Control. The fault management framework provides an alternative to designing a BPEL process with catch activities in scope activities.
This section provides an overview of the components that comprise the fault management framework.
-
The fault management framework catches all faults (business and runtime) for an invoke activity.
-
A fault policy file defines fault conditions and their corresponding fault recovery actions. Each fault condition specifies a particular fault or group of faults, which it attempts to handle, and the corresponding action for it. A set of actions is identified by an ID in the fault policy file.
-
A set of conditions invokes an action (known as a fault policy).
-
Email or JMS notify users of errors associated with a condition.
-
A fault policy bindings file associates the policies defined in the fault policy file with the following:
-
SOA composite applications
-
BPEL process and Oracle Mediator service components
-
Reference binding components for BPEL processes and Oracle Mediator service components
The framework looks for fault policy bindings in the same directory as the
composite.xml
file of the SOA composite application or in a remote location identified by two properties that you set. The remote location is in the MDS Repository.Note:
A fault policy configured with the fault management framework overrides any fault handling defined in catch activities of scope activities in the BPEL process. The fault management framework can be configured to rethrow the fault handling back to the catch activities.
-
-
The fault policy file (
fault-policies.xml
) and fault policy bindings file (fault-bindings.xml
) are placed in either of the following locations:-
In the same directory as the
composite.xml
file of the SOA composite application. -
In a different location that is specified with two properties that you add to the
composite.xml
file. This option is useful if a fault policy must be used by multiple SOA composite applications. This option overrides any fault policy files that are included in the same directory as thecomposite.xml
file. The following example provides details about these two properties. In this example, the fault policy files are placed into the SOA part of the Oracle Metadata Services (MDS) Repository shared area.<property name="oracle.composite.faultPolicyFile">oramds:/apps/faultpolicyfiles/ fault-policies.xml </property> <property name="oracle.composite.faultBindingFile">oramds:/apps/faultpolicyfiles/ fault-bindings.xml </property>
-
For details about Oracle Mediator fault handling capabilities, see Using Error Handling .
For details about creating a fault policy with Oracle Business Process Management (BPM) Suite, see Chapter "Using Fault Handling in BPM" of Developing Business Processes with Oracle Business Process Management Studio.
12.4.1 Understanding How the Fault Policy Binding Resolution Works
A fault policy bindings file associates the policies defined in a fault policy file with the SOA composite application or the component (service component or reference binding component). The framework attempts to identify a fault policy binding in the following order:
-
Reference binding component defined in the
composite.xml
file. -
BPEL process or Oracle Mediator service component defined in the
composite.xml
file. -
SOA composite application defined in the
composite.xml
file.
During the resolution process, if no action is found that matches the condition, the framework assumes that resolution failed and moves to the next resolution level.
For example, assume an invoke activity faults with faultname="abc"
. There is a policy binding specified in the fault-bindings.xml
file:
-
SOA composite application binds to
policy-id-1
-
BPEL process or Oracle Mediator service component or reference binding component binds to
policy-id-2
In the fault-bindings.xml
file, the following bindings are also specified:
-
SOA composite application binds to
policy-id-3
-
Reference binding component or service component binds to
policy-id-4
The fault management framework behaves as follows:
-
First match the resolve binding (in this case,
policy-id-4
). -
If the fault resolution fails, go to the next possible match (
policy-id-2
). -
If the fault resolution fails, go to the next possible match (
policy-id-3
). -
If the fault resolution fails, go to the next possible match (in this case,
policy-id-1
). -
If the fault resolution still fails, the fault is sent to the BPEL fault catch activity.
12.4.2 How to Design a Fault Policy for Automated Fault Recovery with the Fault Policy Wizard
You can design a fault policy with the Fault Policy wizard and associate the fault policy with the fault policy binding file.
To design a fault policy for automated fault recovery with the Fault Policy wizard:
12.4.2.1 Step 1: Defining Property Sets
You first define property sets to associate with JMS alerts, which are defined in Step 2: Defining Alerts. You can associate property sets configuration details such as JMS destinations and connection factories with multiple JMS alerts. For example, for a JMS alert, the destination and queue information and connection factory can be referenced by additional JMS alerts configured in the fault policy.
Note:
You cannot create property sets for email alerts in this release.
-
Click the Properties tab. Table 12-1 provides details about available fields.
Table 12-1 Property Set Selections
For... Then... Email alerts
Email alerts do not support property sets for this release.
JMS queue alerts
-
Click Add to specify the properties and values for JMS alerts. The following properties and associated values are required:
-
jmsDestination: The JNDI name of the configured queue or topic in which the alerts is queued/published.
-
connectionFactory: JNDI name for the configured connection factory to use.
Figure 12-12 shows a property set configured with JMS destination and connection factory values.
Figure 12-12 JMS Property Set Configuration
Description of "Figure 12-12 JMS Property Set Configuration"For an example of a fully-defined fault policy file, including a defined
JMS
propertySet
section, see Step 4 of How to Manually Design a Fault Policy for Automated Fault Recovery. -
12.4.2.2 Step 2: Defining Alerts
-
Click the Alerts tab. Two types of notification alerts are supported:
-
Email: Enables you to configure email recipients to receive alerts when a fault occurs. You must also configure the same email recipients on the Mailer tab of the Workflow Notification Properties page in Oracle Enterprise Manager Fusion Middleware Control. For information, see Configuring Human Workflow Notification Properties in Administering Oracle SOA Suite and Oracle Business Process Management Suite.
-
JMS: Enables you to enqueue the fault to a JMS queue or publish it to a JMS topic. JMS header values can also be specified. The JMS notification can be integrated with a third-party resolution system to handle faults. The third-party resolution system dequeue and subscribes to the targeted queue and topic. Further fine-graining is achieved by consuming messages based on the header property values. The payload type of the JMS message is a text message in XML format. You must also configure JMS queues and topics and connection factories in Oracle WebLogic Server Administration Console. For information, see Configuring Basic JMS System Resources in Administering JMS Resources for Oracle WebLogic Server.
-
-
Click the Add icon. Table 12-2 provides details.
Table 12-2 Alert Selections
If You Select... Then... email
You can specify recipients to receive an email alert when a fault occurs.
-
In the ID field, specify an ID or accept the default value.
-
In the To and CC fields, specify the email recipients.
Note: Do not select any property sets from the Property Set list. The email alert does not support property sets for this release.
-
When complete, click OK.
JMS
You can specify queues to receive a JMS alert when a fault occurs.
Two properties are required for configuring a JMS alert.
-
jmsDestination: The JNDI name of the configured queue or topic on which the alert is queued and published.
-
connectionFactory: The JNDI Name for the configured connection factory to use.
-
In the ID field, specify an ID or accept the default value.
-
In the Property Set list, select an existing property set created in Step 1: Defining Property Sets or click Create Required Properties to create a new property set with values defined for jmsDestination and connectionFactory.
-
In the Headers table, optionally specify JMS header values to achieve finer-grained fault consumption for a JMS alert. Both standard and custom external systems can filter their subscriptions based on the configured header properties.
-
When complete, click OK.
Figure 12-13 shows email alert configuration in the Email Properties dialog.
Figure 12-14 shows JMS alert configuration in the JMS Properties dialog. For this example, both property sets (defined by clicking Create Required Properties to invoke the Property Set dialog) and headers are defined.
For an example of a fully-defined fault policy file, including a defined
Alerts
section, see Step 4 of How to Manually Design a Fault Policy for Automated Fault Recovery. -
12.4.2.4 Step 4: Defining Fault Names and Policies
-
Define the fault name, description, and default action of the fault policy in the upper section of the Fault Policy Editor. Table 12-4 provides details.
Table 12-4 Fault Policy Editor - Upper Section
Element Description Add Fault Policy icon (upper left corner)
You can also add additional fault policies for configuration to a single policy document.
Click the Add icon in the upper left corner to add an additional fault policy. All polices are then displayed in the column on the far left of the Fault Policy Editor. You can click the policy that you want to define.
Delete Fault Policy
Delete a selected fault policy.
Fault Policy
Enter a name for the fault policy or accept the default name of
policy
number
.Add Fault icon (upper right corner)
Click to add a fault.
Delete Fault
Click to delete a fault.
Fault Name
Select a standard type of fault to catch. This list shows the system faults (binding, Oracle Mediator, or remote) or service (business) fault that you can select.
Description
Enter an optional description. The description is persisted into the audit trail during runtime.
Default Action
Perform the following tasks in this section:
-
From the list, select the default action to perform when this fault occurs (for example, abort, rethrow, retry, and so on). The actions available for selection are based on the actions you retained or deleted in Step 3: Defining Actions.
or
-
Click the Add icon to add an if-then condition to the fault policy. This selection displays the If, Then, and Default fields.
For example, if you specify a condition in the If field (the default is true), you can select an action (for example, human intervention) to be invoked in the Then field. If the condition is not true, you can select the default action to occur (for example, abort) in the Default field.
-
In the If field, enter a condition or click the Expression Builder icon to build an XPath expression condition.
-
In the Then field, specify the condition to invoke if the condition in the If field evaluates to true.
-
In the Default field, specify the condition to invoke if the condition in the If field evaluates to false.
-
Click the Alert icon to the left of the Add icon to select the type of alert to send when this condition occurs. The alert types available for selection are displayed in the Alerts tab in this dialog. You can specify multiple alerts on a condition.
When complete, the Fault Policy Editor looks as shown in Figure 12-16.
Figure 12-16 Fault Policy Editor With Fault Name, Description, and Default Actions Defined
Description of "Figure 12-16 Fault Policy Editor With Fault Name, Description, and Default Actions Defined" -
-
Above the SOA Composite Editor, close the fault policy file, and click Yes when prompted to save your changes. Figure 12-17 provides details.
Policy configuration is now complete. You are now ready to associate the fault policy with the fault policy bindings.
12.4.2.5 Step 5: Defining the Fault Policy Bindings for the Fault Policy
After creating a fault policy with the Fault Policy wizard, you associate the fault policy with a fault policy bindings file. The fault policy bindings file associates the policies defined in the fault policy file with service components, service binding components, or reference binding components in the SOA composite application.
12.4.3 How to Manually Design a Fault Policy for Automated Fault Recovery
This section describes how to manually design a fault policy. The recommended approach is to design a fault policy with the Fault Policy wizard, as described in How to Design a Fault Policy for Automated Fault Recovery with the Fault Policy Wizard.
12.4.3.1 Manually Creating a Fault Policy File for Automated Fault Recovery
To manually create a fault policy file for automated fault recovery:
Note:
The preseeded recovery action tag names (ora-retry
, ora-human-intervention
, ora-terminate
, and so on) are only samples. You can substitute these names with ones appropriate to your environment.
A fault policy file with fully-defined condition
, action
, and alert
sections looks as follows:
Note:
-
Fault policy file names are not restricted to one specific name. However, they must conform to the
fault-policy.xsd
schema file. -
This fault policy file provides an example of catching faults based on fault names. You can also catch faults based on message types, or on both:
<faultName name="myfault" type="fault:faultType">
<?xml version="1.0" encoding="UTF-8"?> <faultPolicies xmlns="http://schemas.oracle.com/bpel/faultpolicy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <faultPolicy version="2.0.1" id="ModifyAndRecover" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.oracle.com/bpel/faultpolicy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Conditions> <!-- Handle remoteFault system exceptions --> <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:remoteFault"> <condition> <!--<test>$fault.code="1"</test>--> <alert ref = "ora-jms"/> <alert ref = "ora-email"/> <action ref="default-human-intervention"/> </condition> </faultName> <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:bindingFault"> <condition> <action ref="default-human-intervention"/> </condition> </faultName> </Conditions> <Alerts> <Alert id="ora-email"> <email> <To>joe.smith@example.com</To> <CC>joe.smith@example.com</CC> </email> </Alert> <Alert id="ora-jms"> <JMS propertySet="jms-props"> <Headers> <property name="correlationId">myvalue</property> <property name="correlationId1">myvalue1</property> </Headers> </JMS> </Alert> </Alerts> <Actions> <!-- Generics --> <Action id="default-terminate"> <abort/> </Action> <Action id="default-replay-scope"> <replayScope/> </Action> <Action id="default-rethrow-fault"> <rethrowFault/> </Action> <Action id="default-human-intervention"> <humanIntervention/> </Action> <Action id="ora-retry-with-human-intervention"> <retry> <retryCount>1</retryCount> <retryInterval>2</retryInterval> <exponentialBackoff/> <retryFailureAction ref="default-terminate"/> </retry> </Action> </Actions> <Properties> <propertySet name="jms-props"> <property name="jmsDestination">MyQueue</property> <property name="connectionFactory">jms/fabric/ehconnectionfactory</property> </propertySet> </Properties> </faultPolicy> </faultPolicies>
12.4.3.2 Associating a Fault Policy with Fault Policy Binding
Note:
The fault policy binding file must be named fault-bindings.xml
. This conforms to the fault-bindings.xsd
schema file.
To associate a fault policy with fault policy binding:
12.4.3.3 Additional Fault Policy and Fault Policy Binding File Samples
This section provides additional samples of fault policy and fault policy binding files. The following example shows the fault-policies.xml
file contents.
<?xml version="1.0" encoding="UTF-8"?>
<faultPolicies xmlns="http://schemas.oracle.com/bpel/faultpolicy">
<faultPolicy version="2.0.1"
id="CRM_ServiceFaults"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.oracle.com/bpel/faultpolicy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Conditions>
<!-- Fault if wsdlRuntimeLocation is not reachable -->
<faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
name="bpelx:remoteFault">
<condition>
<test>$fault.code="WSDLReadingError"</test>
<action ref="ora-terminate"/>
</condition>
<condition>
<action ref="ora-java"/>
</condition>
</faultName>
<!-- Fault if location port is not reachable-->
<faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
name="bpelx:bindingFault">
<!--ORA-00001: unique constraint violated on insert-->
<condition>
<test>$fault.code="1"</test>
<action ref="ora-java"/>
</condition>
<!--ORA-01400: cannot insert NULL -->
<condition>
<test xmlns:test="http://test">$fault.code="1400"</test>
<action ref="ora-terminate"/>
</condition>
<!--ORA-03220: required parameter is NULL or missing -->
<condition>
<test>$fault.code="3220"</test>
<action ref="ora-terminate"/>
</condition>
<condition>
<action ref="ora-retry-crm-endpoint"/>
</condition>
</faultName>
<!-- Business faults -->
<!-- Fault comes with a payload of error, make sure the name space is
provided here or at root level -->
<faultName xmlns:credit="http://services.otn.com"
name="credit:NegativeCredit">
<!-- you get this fault when SSN starts with 0-->
<condition>
<test>$fault.payload="Bankruptcy Report"</test>
<alert ref = "ora-email"/>
<action ref="ora-human-intervention"/>
<!--action ref="ora-retry"/-->
</condition>
<!-- you get this fault when SSN starts with 1-->
<condition>
<test>$fault.payload="Bankruptcy Report-abort"</test>
<action ref="ora-terminate"/>
</condition>
<!-- you get this fault when SSN starts with 2-->
<condition>
<test>$fault.payload="Bankruptcy Report-rethrow"</test>
<action ref="ora-rethrow-fault"/>
</condition>
<!-- you get this fault when SSN starts with 3-->
<condition>
<test>$fault.payload="Bankruptcy Report-replay"</test>
<action ref="ora-replay-scope"/>
</condition>
<!-- you get this fault when SSN starts with 4-->
<condition>
<test
xmlns:myError="http://services.otn.com">$fault.payload="Bankruptcy
Report-human"</test>
<action ref="ora-human-intervention"/>
</condition>
<!-- you get this fault when SSN starts with 5-->
<condition>
<test>$fault.payload="Bankruptcy Report-java"</test>
<action ref="ora-java"/>
</condition>
</faultName>
</Conditions>
<Actions>
<Action id="ora-retry">
<retry>
<retryCount>3</retryCount>
<retryInterval>2</retryInterval>
<exponentialBackoff/>
<retryFailureAction ref="ora-java"/>
<retrySuccessAction ref="ora-java"/>
</retry>
</Action>
<Action id="ora-retry-crm-endpoint">
<retry>
<retryCount>5</retryCount>
<retryFailureAction ref="ora-java"/>
<retryInterval>5</retryInterval>
<retrySuccessAction ref="ora-java"/>
</retry>
</Action>
<Action id="ora-replay-scope">
<replayScope/>
</Action>
<Action id="ora-rethrow-fault">
<rethrowFault/>
</Action>
<Action id="ora-human-intervention">
<humanIntervention/>
</Action>
<Action id="ora-terminate">
<abort/>
</Action>
<Action id="ora-java">
<!-- this is user provided class-->
<javaAction
className="com.oracle.bpel.client.config.faultpolicy.TestJavaAction"
defaultAction="ora-terminate" propertySet="prop-for-billing">
<returnValue value="REPLAY" ref="ora-terminate"/>
<returnValue value="RETRHOW" ref="ora-rethrow-fault"/>
<returnValue value="ABORT" ref="ora-terminate"/>
<returnValue value="RETRY" ref="ora-retry"/>
<returnValue value="MANUAL" ref="ora-human-intervention"/>
</javaAction>
</Action>
</Actions>
<Properties>
<propertySet name="prop-for-billing">
<property name="user_email_recipient">bpeladmin</property>
<property name="email_recipient">joe@abc.com</property>
<property name="email_recipient">mike@xyz.com</property>
<property name="email_threshold">10</property>
<property name="sms_recipient">+429876547</property>
<property name="sms_recipient">+4212345</property>
<property name="sms_threshold">20</property>
<property name="user_email_recipient">john</property>
</propertySet>
<propertySet name="prop-for-order">
<property name="email_recipient">john@abc.com</property>
<property name="email_recipient">jill@xyz.com</property>
<property name="email_threshold">10</property>
<property name="sms_recipient">+42222</property>
<property name="sms_recipient">+423335</property>
<property name="sms_threshold">20</property>
</propertySet>
</Properties>
</faultPolicy>
<faultPolicy version="2.0.1"
id="Billing_ServiceFaults"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.oracle.com/bpel/faultpolicy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Conditions>
<faultName>
<condition>
<action ref="ora-manual"/>
</condition>
</faultName>
</Conditions>
<Actions>
<Action id="ora-manual">
<humanIntervention/>
</Action>
</Actions>
</faultPolicy>
</faultPolicies>
The following example shows the fault-bindings.xml
file that associates the fault policies defined in fault-policies.xml
.
<?xml version="1.0" encoding="UTF-8"?> <faultPolicyBindings version="2.0.1" xmlns="http://schemas.oracle.com/bpel/faultpolicy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <composite faultPolicy="ConnectionFaults"/> <component faultPolicy="ServiceFaults"> <name>Component1</name> <name>Component2</name> </component> <!-- Below listed component names use polic CRM_SeriveFaults --> <component faultPolicy="CRM_ServiceFaults"> <name>HelloWorld</name> <name>ShippingComponent</name> <name>AnotherComponent"</name> </component> <!-- Below listed reference names and port types use polic CRM_ServiceFaults --> <reference faultPolicy="CRM_ServiceFaults"> <name>creditRatingService</name> <name>anotherReference</name> <portType xmlns:credit="http://services.otn.com">credit:CreditRatingService</portType> <portType xmlns:db="http://xmlns.oracle.com/pcbpel/adapter/db/insert/">db:insert_ plt</portType> </reference> <reference faultPolicy="test1"> <name>CreditRating3</name> </reference> </faultPolicyBindings>
12.4.3.4 Designing a Fault Policy with Multiple Rejection Handlers
If you design a fault policy that uses the action handler for rejected messages, note that only one write action can be performed. Multiple write actions cannot be performed, even if you define multiple rejection handlers, as shown in the following example. In this case, only the first rejection handler defined (for this example, ora-queue
) is executed.
<faultName xmlns:rjm="http://schemas.oracle.com/sca/rejectedmessages" name="rjm:FileIn"> <condition> <action ref="ora-queue"/> </condition> </faultName> <faultName xmlns:rjm="http://schemas.oracle.com/sca/rejectedmessages" name="rjm:FileIn"> <condition> <action ref="ora-file"/> </condition> </faultName>
12.4.4 How to Execute a Fault Policy
You deploy a fault policy as part of a SOA composite application. After deployment, you can perform the fault recovery actions from Oracle Enterprise Manager Fusion Middleware Control. Actions such as terminate, retry, rethrow, and Java are retried as part of composite execution. No explicit user execution is required. The human intervention action can be manually executed in Oracle Enterprise Manager Fusion Middleware Control.
-
Retry the activity
-
Modify a variable (available to the faulted activity)
-
Continue the instance (mark the activity as a success)
-
Rethrow the exception
-
Abort the instance
-
Throw a replay scope exception
For additional information, see Administering Oracle SOA Suite and Oracle Business Process Management Suite.
12.4.5 How to Use a Java Action Fault Policy
Note the following details when using the Java action fault policy:
-
The Java class provided follows a specific interface. This interface returns a string. Multiple values can be provided for output and the fault policy to take after execution.
-
Additional fault policy can be executed by providing a mapping from the output value (return value) of implemented methods to a fault policy.
-
If no
ReturnValue
is specified, the default fault policy is executed, as shown in the following example.
<Action id="ora-java"> <javaAction className="mypackage.myclass" defaultAction="ora-human-intervention" propertySet="prop-for-billing"> <!--defaultAction is a required attribute, but propertySet is optional--> <!-- attribute--> <ReturnValue value="RETRY" ref="ora-retry"/> <!--value is not nilable attribute & cannot be empty--> <ReturnValue value="RETRHOW" ref="ora-rethrow-fault"/> </javaAction> </Action>
Table 12-7 provides an example of ReturnValue
use.
Table 12-7 System Interpretation of Java Action Fault Policy
Code | Description |
---|---|
<ReturnValue value="RETRY" ref="ora-retry"/> |
Execute the |
<ReturnValue value="" ref="ora-rethrow"/> |
Fails in validation. |
<javaAction className="mypackage.myclass" defaultAction="ora-human-intervention"> |
Execute |
<ReturnValue value="RETRY" ref="ora-retry"/> <ReturnValue value="" ref=""/> |
Fails in validation. |
<javaAction className="mypackage.myclass" defaultAction=" ora-human-intervention"> <ReturnValue></ReturnValue> |
Fails in validation. |
To invoke a Java class, you can provide a class that implements the IFaultRecoveryJavaClass
interface. IFaultRecoveryJavaClass
is included in the fabric-runtime.jar
file. The package name is oracle.integration.platform.faultpolicy
.
The IFaultRecoveryJavaClass
interface has two methods, as shown in the following example:
public interface IFaultRecoveryJavaClass { public void handleRetrySuccess( IFaultRecoveryContext ctx ); public String handleFault( IFaultRecoveryContext ctx ); }
Note the following details:
-
handleRetrySuccess
is invoked upon a successful retry attempt. The retry policy chains to a Java action onretrySuccessAction
. -
handleFault
is invoked to execute a policy of typejavaAction
. -
The fault policy class is packaged and deployed in either of two ways:
-
Package the Java class with the SOA composite application.
-
If the Java class must be shared by multiple SOA composite applications, place it in the shared location (for example,
$MW_HOME/soa/soa/ modules/oracle.soa.ext_11.1.1
). The shared location includes areadme
file that describes how to place the Java class to make it available in the class path.
-
The following example shows the data available with IFaultRecoveryContext
:
public interface IFaultRecoveryContext { /** * Gets implementation type of the fault. * @return */ public String getType(); /** * @return Get property set of the fault policy action being executed. */ public Map getProperties(); /** * @return Get fault policy id of the fault policy being executed. */ public String getPolicyId(); /** * @return Name of the faulted partner link. */ public String getReferenceName(); /** * @return Port type of the faulted reference . */ public QName getPortType(); }
The service engine implementation of this interface provides more information (for example, Oracle BPEL Process Manager). The following example provides details:
public class BPELFaultRecoveryContextImpl extends BPELXExecLetUtil implements IBPELFaultRecoveryContext, IFaultRecoveryContext{ ... }
Oracle BPEL Process Manager-specific data is available with IBPELFaultRecoveryContext
, as shown in the following example:
public interface IBPELFaultRecoveryContext { public void addAuditTrailEntry(String message); public void addAuditTrailEntry(String message, Object detail); public void addAuditTrailEntry(Throwable t); /** * @return Get action id of the fault policy action being executed. */ public String getActionId(); /** * @return Type of the faulted activity. */ public String getActivityId(); /** * @return Name of the faulted activity. */ public String getActivityName(); /** * @return Type of the faulted activity. */ public String getActivityType(); /** * @return Correleation id of the faulted activity. */ public String getCorrelationId(); /** * @return BPEL fault that caused the invoke to fault. */ public BPELFault getFault(); /** * @return Get index value of the instance */ public String getIndex(int i); /** * @return get Instance Id of the current process instance of the faulted * activity. */ public long getInstanceId(); /** * @return Get priority of the current process instance of the faulted * activity. */ public int getPriority(); /** * @return Process DN. */ public ComponentDN getProcessDN(); /** * @return Get status of the current process instance of the faulted * activity. */ public String getStatus(); /** * @return Get title of the current process instance of the faulted * activity. */ public String getTitle(); public Object getVariableData(String name) throws BPELFault; public Object getVariableData(String name, String partOrQuery) throws BPELFault; public Object getVariableData(String name, String part, String query) throws BPELFault; /** * @param priority * Set priority of the current process instance of the faulted * activity. * @return */ public void setPriority(int priority); /** * @param status * Set status of the current process instance of the faulted * activity. */ public void setStatus(String status); /** * @param title * Set title of the current process instance of the faulted * activity. * @return */ public String setTitle(String title); public void setVariableData(String name, Object value) throws BPELFault; public void setVariableData(String name, String partOrQuery, Object value) throws BPELFault; public void setVariableData(String name, String part, String query, Object value) throws BPELFault; }
The following example provides an example of javaAction
implementation.
public class TestJavaAction implements IFaultRecoveryJavaClass { public void handleRetrySuccess(IFaultRecoveryContext ctx) { System.out.println("This is for retry success"); handleFault(ctx); } public String handleFault(IFaultRecoveryContext ctx) { System.out.println("-----Inside handleFault-----\n" + ctx.toString()); dumpProperties(ctx.getProperties()); /* Get BPEL specific context here */ BPELFaultRecoveryContextImpl bpelCtx = (BPELFaultRecoveryContextImpl) ctx; bpelCtx.addAuditTrailEntry("hi there"); System.out.println("Policy Id" + ctx.getPolicyId()); ... }
12.4.6 How to Design Fault Policies for Oracle BPM Suite
You can design and execute fault policies for Oracle BPM Suite. For more information, see Chapter "Using Fault Handling in BPM" of Developing Business Processes with Oracle Business Process Management Studio.
12.4.7 What You May Need to Know About Designing a Fault Policy in a Synchronous BPEL Process
When designing a fault policy in a synchronous process, do not specify the following actions. These actions cause dehydration in a synchronous process and leads to timeouts.
-
Retry
-
Human intervention
-
Terminate
12.4.8 What You May Need to Know About Fault Management Behavior When the Number of Instance Retries is Exceeded
When you configure a fault policy to recover instances with the ora-retry
action and the number of specified instance retries is exceeded, the instance is marked as open.faulted
(in-flight state). The instance remains active.
Marking instances as open.faulted
ensures that no instances are lost. You can then configure another fault handling action following the ora-retry
action in the fault policy file, such as the following:
-
Configure an
ora-human-intervention
action to manually perform instance recovery from Oracle Enterprise Manager Fusion Middleware Control. -
Configure an
ora-terminate
action to close the instance (mark it asclosed.faulted
) and never retry again.
However, if you do not set an action to be performed after an ora-retry
action in the fault policy file and the number of instance retries is exceeded, the instance remains marked as open.faulted
, and recovery attempts to handle the instance.
For example, if no action is defined in the fault policy file shown in the following code after ora-retry
:
<Action id="ora-retry"> <retry> <retryCount>2</retryCount> <retryInterval>2</retryInterval> <exponentialBackoff/> </retry> </Action>
The following actions are performed:
-
The invoke activity is attempted (using the above-mentioned fault policy code to handle the fault).
-
Two retries are attempted at increasing intervals (after two seconds, then after four seconds).
-
If all retry attempts fail, the following actions are performed:
-
A detailed fault error message is logged in the audit trail.
-
The instance is marked as
open.faulted
(in-flight state). -
The instance is picked up and the invoke activity is re-attempted.
-
-
Recovery may also fail. In that case, the invoke activity is re-executed. Additional audit messages are logged.
12.4.9 What You May Need to Know About Binding Level Retry Execution Within Fault Policy Retries
If you are testing retry actions on adapters with both JCA-level retries for the outbound direction and a retry action in the fault policy file for outbound failures, the JCA-level (or binding level) retries are executed within the fault policy retries. For example, assume you have designed the application shown in Figure 12-22:
You specify the retry parameters, as shown below, in the composite.xml
file:
<property name="jca.retry.count" type="xs:int" many="false" override="may">2</property> <property name="jca.retry.interval" type="xs:int" many="false" override="may">2</property> <property name="jca.retry.backoff" type="xs:int" many="false" override="may">2</property>
In the fault policy file for the EQ reference binding component for the outbound direction, you specify the actions shown in the following code:
<retryCount>3</retryCount> <retryInterval>3</retryInterval>
If an outbound failure occurs, the expected behavior is for the JCA retries to occur within the fault policy retries. When the first retry of the fault policy is executed, the JCA retry is called. In this example, a JCA retry of 2
with an interval of 2
seconds and exponential back off of 2
is executed for every retry of the fault policy:
-
Fault policy retry 1:
-
JCA retry 1 (with
2
seconds interval) -
JCA retry 2 (with
4
seconds interval)
-
-
Fault policy retry 2:
-
JCA retry 1 (with
2
seconds interval) -
JCA retry 2 (with
4
seconds interval)
-
-
Fault policy retry 3:
-
JCA retry 1 (with
2
seconds interval) -
JCA retry 2 (with
4
seconds interval)
-
12.5 Catching BPEL Runtime Faults
BPEL runtime faults can be caught as a named BPEL fault. The bindingFault
and remoteFault
can be associated with a message. This action enables the faultHandler
to get details about the faults.
12.6 Getting Fault Details with the getFaultAsString XPath Extension Function
The catchAll activity is provided to catch possible faults. However, BPEL does not provide a method for obtaining additional information about the captured fault. Use the getFaultAsString()
XPath extension function to obtain additional information.
12.6.1 How to Get Fault Details with the getFaultAsString XPath Extension Function
The following example shows how to use this function.
<catchAll>
<sequence>
<assign>
<from expression="bpelx:getFaultAsString()"/>
<to variable="faultVar" part="message"/>
</assign>
<reply faultName="ns1:myFault" variable="faultVar" .../>
</sequence>
</catchAll>
For more information, see getFaultAsString.
12.7 Throwing Internal Faults with the Throw Activity
A BPEL application can generate and receive fault messages. The throw activity has three elements: its name, the name of the fault, and the fault variable. The fault thrown by a throw activity is internal to BPEL. You cannot use a throw activity on an asynchronous process to communicate with a client. Throw activity syntax includes the throw name, fault name, and fault variable:
<throw name="delay" faultName="nsPrefix:fault-1" faultVariable="fVar"/>
12.8 Rethrowing Faults with the Rethrow Activity
The rethrow activity rethrows faults originally captured by the immediately enclosing fault handler. Only use the rethrow activity within a fault handler (for example, within catch and catchAll activities). The rethrow activity is used in fault handlers to rethrow the captured fault (that is, the fault name and the fault data (if present) of the original fault). The rethrow activity must ignore modifications to fault data. For example:
-
If the fault handler modifies fault data and then calls a rethrow activity, the original fault data is rethrown, and not the modified fault data.
-
If a fault is captured using the functionality that enables message type faults with one part defined using an element to be caught by fault handlers looking for the same element type, then the rethrow activity rethrows the original message type data.
Note:
This activity is supported in BPEL version 2.0 projects.
12.8.2 What Happens When You Rethrow Faults
The following example shows the .bpel
file after design is complete for a rethrow activity. The rethrow activity is inside a fault handler (catch activity).
<scope name="scope1"> <faultHandlers> <catch faultName="tns:error" faultVariable="tmpVar" faultElement="tns:fault"> <sequence> <assign> <copy> <from>concat('caught fault: ', $tmpVar)</from> <to>$output.payload</to> </copy> </assign> <rethrow name="Rethrow_1"/> </sequence> </catch> </faultHandlers> <throw faultName="tns:error" faultVariable="fault"/> </scope>
12.9 Returning External Faults
A BPEL process service component can send a fault to another application to indicate a problem, as opposed to throwing an internal fault. In a synchronous operation, the reply activity can return the fault. In an asynchronous operation, the invoke activity performs this function.
12.9.1 How to Return a Fault in a Synchronous Interaction
The syntax of a reply activity that returns a fault in a synchronous interaction is shown in the following example:
<reply partnerlinke="partner-link-name
" portType="port-type-name
" operation="operation-name
" variable="variable-name
" (optional) faultName="fault-name
"> </reply>
Always returning a fault in response to a synchronous request is not very useful. It is better to make the activity part of a conditional branch, in which the first branch is executed if the data requested is available. If the requested data is not available, then the BPEL process service component returns a fault with this information.
For more information, see the following chapters:
-
Invoking a Synchronous Web Service from a BPEL Process for synchronous interactions
-
Using Conditional Branching in a BPEL Process for setting up the conditional structure
12.9.2 How to Return a Fault in an Asynchronous Interaction
In an asynchronous interaction, the client does not wait for a reply. The reply activity is not used to return a fault. Instead, the BPEL process service component returns a fault using a callback operation on the same port type that normally receives the requested information, with an invoke activity.
For more information about asynchronous interactions, see Invoking an Asynchronous Web Service from a BPEL Process.
12.10 Managing a Group of Activities with a Scope Activity
A scope activity provides a container and a context for other activities. A scope provides handlers for faults, events, compensation, data variables, and correlation sets. Using a scope activity simplifies a BPEL flow by grouping functional structures. This grouping enables you to collapse them into what appears to be a single element in Oracle BPEL Designer.
The following example shows a scope named Scope_FulfillOrder
. This scope invokes the FulfillOrder
Oracle Mediator component, which determines the shipping method for the order.
<scope name="Scope_FulfillOrder"> <variables> <variable name="lFulfillOrder_InputVariable" messageType="ns17:requestMessage"/> </variables> <sequence> <assign name="Assign_OrderData"> <copy> <from variable="gOrderInfoVariable" query="/ns4:orderInfoVOSDO"/> <to variable="lFulfillOrder_InputVariable" part="request" query="/ns4:orderInfoVOSDO"/> </copy> </assign> <invoke name="Invoke_FulfillOrder" inputVariable="lFulfillOrder_InputVariable" partnerLink="FulfillOrder.FulfillOrder" portType="ns17:execute_ptt" operation="execute"/> </sequence> </scope>
12.10.2 How to Add Descriptive Notes and Images to a Scope Activity
You can add descriptive notes to scope activities that provide simple descriptions of the functionality of the scope. You can also change the graphical image of scopes. The notes and images display in Oracle BPEL Designer. This helps to make a scope easier to understand.
To add descriptive notes and images to a scope activity:
12.10.3 What Happens After You Create a Scope Activity
The following example shows the scope activity in the .bpel
file after design completion. The Scope_AuthorizeCreditCard
scope activity consists of activities that perform the following actions:
-
A catch activity for catching faulted orders in which the credit card number is not provided or the credit type is not valid.
-
A throw activity that throws a fault for orders that are not approved.
-
An assign activity that takes the credit card type, credit card number, and purchase amount, and assigns this information to the input variable for the
CreditCardAuthorizationService
service. -
An invoke activity that calls a
CreditCardAuthorizationService
service to retrieve customer information. -
A switch activity that checks the results of the credit card validation.
<scope name="Scope_AuthorizeCreditCard"> <variables> <variable name="lCreditCardInput" messageType="ns2:CreditAuthorizationRequestMessage"/> <variable name="lCreditCardOutput" messageType="ns2:CreditAuthorizationResponseMessage"/> </variables> <faultHandlers> <catch faultName="bpws:selectionFailure"> <sequence> <assign name="Assign_noCCNumber"> <copy> <from expression="string('CreditCardCheck - NO CreditCard')"/> <to variable="gOrderProcessorFaultVariable" part="code"/> </copy> </assign> <throw name ="Throw_NoCreditCard" faultVariable="gOrderProcessorFaultVariable" faultName="ns9:OrderProcessingFault"/> </sequence> </catch> <catch faultName="ns2:InvalidCredit"> <sequence> <assign name="Assign_InvalidCreditFault"> <copy> <from expression="concat(bpws:getVariableData ('gOrderInfoVariable','/ns4:orderInfoVOSDO/ ns4:CardTypeCode'), ' is not a valid creditcard type')"/> <to variable="gOrderProcessorFaultVariable" part="summary"/> </copy> <copy> <from expression="string('CreditCardCheck - NOT VALID')"/> <to variable="gOrderProcessorFaultVariable" part="code"/> </copy> </assign> <throw name="Throw_OrderProcessingFault" faultName="ns9:OrderProcessingFault" faultVariable="gOrderProcessorFaultVariable"/> </sequence> </catch> </faultHandlers> <sequence> <assign name="Assign_CreditCheckInput"> <copy> <from variable="gOrderInfoVariable" query="/ns4:orderInfoVOSDO/ns4:OrderTotal"/> <to variable="lCreditCardInput" part="Authorization" query="/ns8:AuthInformation/ns8:PurchaseAmount"/> </copy> <copy> <from variable="gOrderInfoVariable" query="/ns4:orderInfoVOSDO/ns4:CardTypeCode"/> <to variable="lCreditCardInput" part="Authorization" query="/ns8:AuthInformation/ns8:CCType"/> </copy> <copy> <from variable="gOrderInfoVariable" query="/ns4:orderInfoVOSDO/ns4:AccountNumber"/> <to variable="lCreditCardInput" part="Authorization" query="/ns8:AuthInformation/ns8:CCNumber"/> </copy> </assign> <invoke name="InvokeCheckCreditCard" inputVariable="lCreditCardInput" outputVariable="lCreditCardOutput" partnerLink="CreditCardAuthorizationService" portType="ns2:CreditAuthorizationPort" operation="AuthorizeCredit"/> <switch name="Switch_EvaluateCCResult"> <case condition="bpws:getVariableData('lCreditCardOutput','status',' /ns8:status') != 'APPROVED'"> <bpelx:annotation> <bpelx:pattern>status <> approved</bpelx:pattern> </bpelx:annotation> <throw name="Throw_Fault_CC_Denied" faultName="client:OrderProcessorFault"/> </case> /switch> </sequence> </scope>
12.10.4 What You May Need to Know About Scopes
Scopes can use a significant amount of CPU and memory and should not be overused. Sequence activities use less CPU and memory and can make large BPEL flows more readable.
12.10.5 How to Use a Fault Handler Within a Scope
If a fault is not handled, it creates a faulted state that migrates up through the application and can throw the entire process into a faulted state. To prevent this from occurring, place the parts of the process that have the potential to receive faults within a scope. The scope activity includes the following fault handling capabilities:
-
The catch activity works within a scope to catch faults and exceptions before they can throw the entire process into a faulted state. You can use specific fault names in the catch activity to respond in a specific way to an individual fault.
-
The catchAll activity catches any faults that are not handled by name-specific catch activities.
The following example shows the syntax for catch and catchAll activities. Assume that a fault named x:foo
is thrown. The first catch is selected if the fault carries no fault data. If there is fault data associated with the fault, the third catch is selected if the type of the fault's data matches the type of variable bar
. Otherwise, the default catchAll handler is selected. Finally, a fault with a fault variable whose type matches the type of bar
and whose name is not x:foo
is processed by the second catch. All other faults are processed by the default catchAll handler.
<faulthandlers> <catch faultName="x:foo"> <empty/> </catch> <catch faultVariable="bar"> <empty/> </catch> <catch faultName="x:foo" faultVariable="bar"> <empty/> </catch> <catchAll> <empty/> </catchAll> </faulthandlers>
12.10.6 What You May Need to Know About the idempotent Property and Fault Handling
If the idempotent
deployment descriptor property is set to false
in the composite.xml
file and the invocation of a partner link fails, recovery does not start from the invoke activity. Relying on the idempotent
property for retrying the invoke activity is not recommended. Instead, recovery is attempted by fault handling you have designed into the BPEL process (such as with a catchAll activity). As a best practice, Oracle recommends that you instead use a fault policy to retry the invoke activity.
Table 12-8 describes the behavior when the idempotent
property is set to false
and partner link invocation either succeeds or fails.
Table 12-8 Recovery Behavior When the idempotent Property Is Set to False
If Partner Link Invocation Is... | Then... |
---|---|
Successful |
The invoke activity is dehydrated immediately after execution and recorded in the dehydration store. |
Unsuccessful, and your BPEL process includes fault handling, such as a catchAll activity |
Recovery is started from the catchAll activity and not from the invoke activity. |
Unsuccessful, and your BPEL process includes a fault policy |
The fault policy is used to attempt recovery of the invoke activity. This is the recommended approach. |
For example, assume your BPEL process includes the following design:
-
An invoke activity invokes a partner link (for this example, named
myPartnerLink
). -
The
idempotent
deployment descriptor property is set tofalse
in thecomposite.xml
file.<property name="bpel.partnerLink.myPartnerLink.idempotent">false</property>
This setting causes the BPEL process to dehydrate immediately after execution of this activity and be recorded in the dehydration store.
You can also set this property to
false
in the Edit Partner Link dialog. Figure 12-29 provides details.Figure 12-29 Idempotence Tab of Edit Partner Link Dialog
Description of "Figure 12-29 Idempotence Tab of Edit Partner Link Dialog"For more information, see Managing Idempotence at the Partner Link Operation Level.
-
A catchAll activity error handler in a scope activity catches faults and throws a rollback fault.
If the invocation by the invoke activity to the partner link fails, recovery starts from the catchAll activity error handler, and not from the invoke activity. The recovery from the catchAll activity can be observed in the flow activity for the BPEL process in Oracle Enterprise Manager Fusion Middleware Control.
This is by design. The idempotent
property setting is checked after execution of the invoke activity. If the execution failed and an exception is raised, the idempotent
property setting is never reached. The BPEL process service engine saves the instance right after opening the catchAll activity. The instance must be saved because the idempotent
property is set to false
. This is why recovery resumes in the catchAll activity.
Oracle recommends that you instead recover the failed invoke activity with a fault policy. For more information about creating fault polices, see Handling Faults with the Fault Management Framework.
For more information about the idempotent
property, see Introduction to Deployment Descriptor Properties.
12.10.8 What Happens When You Create a Catch Activity in a Scope
The following example shows the catch activity in the .bpel
file after design completion. The selectionFailure
catch activity catches orders in which the credit card number is not provided and the InvalidCredit
catch activity catches credit types that are not valid.
<faultHandlers> <catch faultName="bpws:selectionFailure"> <sequence> <assign name="Assign_noCCNumber"> <copy> <from expression="string('CreditCardCheck - NO CreditCard')"/> <to variable="gOrderProcessorFaultVariable" part="code"/> </copy> </assign> <throw name ="Throw_NoCreditCard" faultVariable="gOrderProcessorFaultVariable" faultName="ns9:OrderProcessingFault"/> </sequence> </catch> <catch faultName="ns2:InvalidCredit"> <sequence> <assign name="Assign_InvalidCreditFault"> <copy> <from expression="concat(bpws:getVariableData ('gOrderInfoVariable','/ns4:orderInfoVOSDO/ns4:CardTypeCode'), ' is not a valid creditcard type')"/> <to variable="gOrderProcessorFaultVariable" part="summary"/> </copy> <copy> <from expression="string('CreditCardCheck - NOT VALID')"/> <to variable="gOrderProcessorFaultVariable" part="code"/> </copy> </assign> <throw name="Throw_OrderProcessingFault" faultName="ns9:OrderProcessingFault" faultVariable="gOrderProcessorFaultVariable"/> </sequence> </catch> </faultHandlers>
If no catch or catchAll activity is selected, the fault is not caught by the current scope and is rethrown to the immediately enclosing scope. If the fault occurs in (or is rethrown to) the global process scope, and there is no matching fault handler for the fault at the global level, the process terminates abnormally. This is as though a terminate activity (described in Stopping a Business Process Instance with the Terminate Activity in BPEL 1.1) had been performed.
12.10.9 How to Insert No-Op Instructions into a Business Process with an Empty Activity
There is often a need to use an activity that does nothing. An example is when a fault must be caught and suppressed. In this case, you can use the empty activity to insert a no-op instruction into a business process.
To create an empty activity:
12.11 Re-executing Activities in a Scope Activity with the Replay Activity
You can create a replay activity inside a scope activity to re-execute all of the activities inside the scope.
12.11.2 What Happens When You Create a Replay Activity
The following example shows the .bpel
file after design is complete for a replay activity in a BPEL project that supports BPEL version 2.0. In BPEL 2.0, the replay activity is wrapped in an extensionActivity
element.
<scope name="scope2"> <sequence> <assign> <copy> <from>$counter2 + 1</from> <to>$counter2</to> </copy> </assign> <scope name="scope3"> <sequence> <assign> <copy> <from>$counter + 1</from> <to>$counter</to> </copy> </assign> <if> <condition>$counter = 3</condition> <empty/> <else> <extensionActivity> <bpelx:replay name="ReplayScope" scope="Scope_RetrieveOrder"/> </extensionActivity> </else> </if> </sequence> </scope> </sequence> </scope>
In BPEL 1.1, the replay activity is coded as a bpelx
extension.
<bpelx:replay name="ReplayScope" scope="Scope2"/>
12.12 Using Compensation After Undoing a Series of Operations
Compensation occurs when the BPEL process service component cannot complete a series of operations after some have completed, and the BPEL process service component must backtrack and undo the previously completed transactions. For example, if a BPEL process service component is designed to book a rental car, a hotel, and a flight, it may book the car and the hotel and then be unable to book a flight for the right day. In this case, the BPEL flow performs compensation by going back and unbooking the car and the hotel.
In a scope activity, the compensation handler can reverse previously completed process steps. The compensation handler can be invoked after successful completion of its associated scope with either of the following activities.
-
Compensate activity (in BPEL version 1.1 and 2.0 projects)
This activity causes the compensation handler of all successfully completed and not yet compensated child scopes to be executed in default order.
-
compensateScope activity (in a BPEL version 2.0 project)
This activity causes the compensation handler of one specific successfully completed scope to be executed.
12.12.1 Using a Compensate Activity
You can invoke a compensation handler by using the compensate activity, which names the scope for which the compensation is to be performed (that is, the scope whose compensation handler is to be invoked). A compensation handler for a scope is available for invocation only when the scope completes normally. Invoking a compensation handler that has not been installed is equivalent to using the empty activity (it is a no-op). This ensures that fault handlers do not have to rely on state to determine which nested scopes have completed successfully. The semantics of a process in which an installed compensation handler is invoked multiple times are undefined.
The ability to explicitly invoke the compensate activity is the underpinning of the application-controlled error-handling framework of the Business Process Execution Language for Web Services Specification. You can use this activity only in the following parts of a business process:
-
In a fault handler of the scope that immediately encloses the scope for which to perform compensation.
-
In the compensation handler of the scope that immediately encloses the scope for which to perform compensation.
For example:
<compensate scope="RecordPayment"/>
If a scope being compensated by name was nested in a loop, the BPEL process service component invokes the instances of the compensation handlers in the successive iterations in reverse order.
If the compensation handler for a scope is absent, the default compensation handler invokes the compensation handlers for the immediately enclosed scopes in the reverse order of the completion of those scopes.
The compensate form, in which the scope name is omitted in a compensate activity, explicitly invokes this default behavior. This is useful when an enclosing fault or compensation handler must perform additional work, such as updating variables or sending external notifications, in addition to performing default compensation for inner scopes. The compensate activity in a fault or compensation handler attached to the outer scope invokes the default order of compensation handlers for completed scopes directly nested within the outer scope. You can mix this activity with any other user-specified behavior except for the explicit invocation of the nested scope within the outer scope. Explicitly invoking compensation for such a scope nested within the outer scope disables the availability of default-order compensation.
12.12.3 What Happens When You Create a Compensate Activity
If a scope activity has a compensation handler defined inline, then the name of the activity is the name of the scope to be used in the compensate activity. The syntax is shown in the following example:
<compensate scope="ncname"? standard-attributes> standard-elements </compensate>
12.12.4 Using a compensateScope Activity in BPEL 2.0
The compensateScope activity is used to start compensation on a specified inner scope that has already completed successfully. Use this activity only from within a fault handler, another compensation handler, or a termination handler.
When you create a compensateScope activity, you select a target that must refer to the immediately-enclosed scope. The scope must include a fault handler or compensation handler.
12.12.5 How to Create a compensateScope Activity
Note:
This activity is supported in BPEL 2.0 projects.
To create a compensateScope activity:
12.12.6 What Happens When You Create a compensateScope Activity
The following example shows the .bpel
file after design is complete for a compensateScope activity. The compensateScope activity is defined in a catchall fault handler. The scope in which to invoke the compensation handler is defined.
<scope name="ScopeAssignCreditRating">
<faultHandlers>
<catchAll>
<compensateScope target="ScopeAssignScreditRating2" />
</catchAll>
</faultHandlers>
<sequence>
<scope name="ScopeAssignScreditRating2">
<compensationHandler>
<!-- undo work -->
</compensationHandler>
<!-- do some work -->
</scope>
<!-- do more work -->
<!-- a fault is thrown here; results of ScopeAssignScreditRating2 must be undone -->
</sequence>
</scope>
12.13 Stopping a Business Process Instance with a Terminate or Exit Activity
You can stop a business process instance with either of the following activities:
-
Exit activity (in a BPEL version 2.0 project)
-
Terminate activity (in a BPEL version 1.1 project)
12.13.1 Immediately Ending a Business Process Instance with the Exit Activity in BPEL 2.0
You can use the exit activity to immediately end all currently running activities on all parallel branches without involving any termination handling, fault handling, or compensation handling mechanisms. This activity is useful for environments in which there may not be a reasonable way for dealing with unexpected, severe failures.
Note:
Any open conversations are also impacted by the exit activity. For example, other partners interacting with the process may wait for a response that never arrives.
12.13.1.2 What Happens When You Create an Exit Activity
The following example shows the .bpel
file after design is complete for an exit activity.
<sequence>
<!-- receive input from requester -->
<receive name="receiveInput" partnerLink="client" portType="tns:Test"
operation="process" variable="input" createInstance="yes"/>
<assign>
<copy>
<from>$input.payload</from>
<to>$output.payload</to>
</copy>
</assign>
<!-- respond output to requester -->
<reply name="replyOutput" partnerLink="client"
portType="tns:Test" operation="process" variable="output"/>
<exit/>
</sequence>
12.13.2 Stopping a Business Process Instance with the Terminate Activity in BPEL 1.1
The terminate activity immediately terminates the behavior of a business process instance within which the terminate activity is performed. All currently running activities must be terminated as soon as possible without any fault handling or compensation behavior. The terminate activity does not send any notifications of the status of a BPEL process service component. If you are going to use the terminate activity, first program notifications to the interested parties.
12.14 Throwing Faults with Assertion Conditions
You can specify an assertion condition in BPEL versions 1.1 and 2.0 that is executed upon receipt of a callback message in request-response invoke activities, receive activities, reply activities, and onMessage branches of pick and scope activities. The assertion specifies an XPath expression that, when evaluated to false, causes a BPEL fault to be thrown from the activity. This condition provides an alternative to creating a potentially large number of switch, assign, and throw activities after a partner callback.
You can select when to execute a condition:
-
Preassert: This condition is executed before the invoke or reply activity send out the outbound message.
-
Postassert: This condition is executed after an invoke activity, receive activity, or onMessage branch receives the inbound message.
12.14.1 How to Create Assertion Conditions
You can create assertion conditions in the following activities:
-
In message exchange activities such as invoke activities, receive activities, reply activities, and OnMessage branches
-
In standalone assert activities for specifying XPath expressions
12.14.1.1 To create assertion conditions in invoke activities, receive activities, reply activities, and OnMessage branches:
-
In the SOA Composite Editor, double-click the BPEL process service component.
-
In the Components window, expand BPEL Constructs.
-
Drag a Receive activity, Invoke activity, Pick activity, or Scope activity into the designer.
-
Expand the Receive, Invoke, or onMessage branch of the Pick or Scope activity.
-
Click the Assertions tab.
-
If you are creating an assertion for a BPEL 2.0 project, perform the following tasks. Otherwise, go to Step 6.
-
Select when to execute the condition. Table 12-9 provides details.
Table 12-9 Assertion Condition Tabs
To Create A... Select The... Preassertion condition
Pre Asserts tab
Postassertion condition
Post Asserts tab
-
Click the Add icon, as shown in Figure 12-41.
Figure 12-41 Add Icon of Assertions Tab in BPEL 2.0
Description of "Figure 12-41 Add Icon of Assertions Tab in BPEL 2.0"
The Assert dialog is displayed.
-
-
If you are creating an assertion for a BPEL 1.1 project, perform the following tasks.
-
Click the Add icon, as shown in Figure 12-42.
Figure 12-42 Add Icon of Assertions Tab in BPEL 1.1
Description of "Figure 12-42 Add Icon of Assertions Tab in BPEL 1.1" -
Select when to execute the condition. Table 12-10 provides details.
Table 12-10 Condition Execution Options
Element Description Pre Assert
If selected, the condition is executed before the invoke or reply activity send out the outbound message.
Note: A fault policy does not handle faults thrown from a preassert condition. Only faults thrown from a postassert condition are supported. For more information about fault policies, see Handling Faults with the Fault Management Framework.
Post Assert
If selected, the condition is executed after an invoke activity, receive activity, or onMessage branch receives the inbound message.
Based on your selection, the Pre Assert or Post Assert dialog is displayed.
-
-
Specify values for the assertion condition, as shown in Figure 12-43. For this example, Post Assert was selected for an assertion condition on a receive activity in a BPEL 2.0 project.
-
Select the Fault QName to be thrown by clicking the Search icon and selecting an existing fault from the Fault Chooser dialog. You can also provide your own values for the Namespace URI and Local Part fields of the fault. If you do not specify anything for the Fault QName, then a
bpelx:assertFailure
fault is thrown.
-
-
When complete, click OK to return to the Assertions tab of the activity. The completed assertion condition is displayed, as shown in Figure 12-44.
-
Click Apply, then OK.
12.14.1.2 To create an assertion condition in standalone assert activities:
-
In the SOA Composite Editor, double-click the BPEL process service component.
-
In the Components window, expand Oracle Extensions.
-
Drag an Assert activity into the designer, as shown in Figure 12-45.
Figure 12-45 Assert Activity in Components Window
Description of "Figure 12-45 Assert Activity in Components Window" -
Expand the Assert activity.
-
To the right of the Expression field, click the XPath Expression Builder icon.
-
Create an expression.
-
When complete, click OK.
The Assert dialog looks as shown in Figure 12-46.
-
Click Apply, then OK.
12.14.2 How to Disable Assertions
You can disable assertions in either of two ways:
-
By setting the System MBean Browser property DisableAsserts to true in Oracle Enterprise Manager Fusion Middleware Control.
-
By setting
bpel.config.disableAsserts
totrue
in thecomposite.xml
file of the SOA composite application, as shown in the following example:<component name="AsyncBPELClient"> <implementation.bpel src="AsyncBPELClient.bpel"/> <property name="bpel.config.disableAsserts">true</property> </component>
For more information about setting System MBean Browser properties, see Administering Oracle SOA Suite and Oracle Business Process Management Suite.
12.14.3 What Happens When You Create Assertion Conditions
The code segment in the .bpel
file defines the specific operation after design completion.
For the following BPEL1.1 example, the bpelx:assert
condition in the invoke activity, when evaluated to false (for example, a credit rating of 0
is submitted), returns a Negative
Credit
message. If the condition evaluates to true, no fault is thrown from the invoke activity and the remaining activities in the BPEL process flow are executed normally.
<invoke name="callbackClient" partnerLink="internalwarehouseservice_client" portType="client:InternalWarehouseServiceCallback" operation="processResponse" inputVariable="outputVariable"> <bpelx:assert name="negativeCredit" expression="$crOutput.payload/tns:rating > 0" message="Negative Credit"/> </invoke>
In the BPEL 1.1 example that follows, the bpelx:assert
condition in the standalone assert activity, when evaluated to false, returns the following message:
got assertion failure on true expression
If the condition evaluates to true, no fault is thrown from the assert activity and the remaining activities in the BPEL process flow are executed normally.
<bpelx:assert expression="true()bpws:getLinkStatus()" message="'got assertion failure on true expression'"
12.14.4 What You May Need to Know About Assertion Conditions
This section describes key assertion condition concepts.
12.14.4.1 bpelx:postAssert and bpelx:preAssert Extensions
Depending upon the activity, you can specify when to execute a condition by clicking the Add icon in the Assertions tab of invoke, receive, reply, and onMessage branches of pick and scope activities, and selecting either Pre Assert or Post Assert. Based on your selection, the following bpelx
extensions are used:
-
bpelx:preAssert
: If you select Pre Assert, the condition is executed before the invoke or reply activity send out the outbound message. -
bpelx:postAssert
: If you select Post Assert, the condition is executed after an invoke activity, receive activity, or onMessage branch receives the inbound message.
The following example shows multiple bpelx:postAssert
extensions in a receive activity in BPEL 1.1:
<receive name="Receive_1" createInstance="no" variable="Receive_1_processResponse_InputVariable" partnerLink="AsyncBPELService" portType="ns1:AsyncBPELServiceCallback" bpelx:for="'PT10S'" operation="processResponse"> <bpelx:postAssert name="assert1" expression="true()" message="'assert true failed'" faultName="client:fault1"/> <bpelx:postAssert name="assert2" expression="false()" message="'assert false failed'" faultName="client:fault2"/> </receive>
The following example shows multiple bpelx:preAssert
extensions in an invoke activity in BPEL 1.1:
<invoke name="Invoke_1" inputVariable="Invoke_1_process_InputVariable" outputVariable="Receive_1_processResponse_InputVariable" partnerLink="SyncBPELService" portType="ns1:SyncBPELService" operation="process"> <bpelx:preAssert name="assert1" expression="true()" message="'assert true failed'"/> <bpelx:preAssert name="assert2" expression="bpws:getVariableData('counter') = 3" message="concat('The value of counter is ', $counter)"/>
For information on using the Assertions tab, see How to Create Assertion Conditions.
12.14.4.2 Use of faultName and message Attributes
You can specify the faultName
and message
attributes of the bpelx:postAssert
element, as shown in the schema definition in the following example for BPEL 1.1.
<invoke | receive | onMessage> standard-elements <bpelx:postAssert name="ncname"? expression="boolean-expr" faultName="QName"+ message="generic-expr"+/> * </invoke | receive | onMessage>
The following example shows the syntax for the faultname
and message
attributes.
<bpelx:postAssert name="Assert_2" message='multiple post assert Greater value fired' faultName="ns2:GreaterValue" expression="bpws:getVariableData('invar','payload','/ns1:process/ns1:input') < 500"/>
If you do not specify the faultName
attribute, the fault defaults to bpelx:postAssertFailure
. If the message
attribute is not specified, the message value defaults to the name of the activity.
<bpelx:postAssert expression="boolean-expr" />
The specified fault is thrown whenever the assertion condition evaluates to false. Analysis is performed on the faultName
QName
to ensure that it properly resolves to a fault that is defined in the partner WSDL portType
. The message expression is a general expression that can evaluate to any XPath value type (string, number, or boolean). If a nonstring value is returned, the string equivalent of the value is used.
12.14.4.3 Multiple Assertions
You can nest multiple assertions in receive activities, invoke activities, and the onMessage branch of pick and scope activities, with evaluation of the assertions continuing in the order in which they were declared until an expression evaluates to false. The following example provides details:
<invoke name="invokeCR" partnerLink="creditRatingService" portType="services:CreditRatingService" operation="process" inputVariable="crInput" outputVariable="crOutput"> <bpelx:postAssert name="negativeCredit" expression="$crOutput.payload/tns:rating > 0" faultName="services:NegativeCredit" message="'Negative Credit'" /> <bpelx:postAssert name="insufficientCredit" expression="$crOutput.payload/tns:rating > 600" faultName="services:InsufficientCredit" message="'Insufficient Credit'" /> </invoke>
In the preceding example, the assertion with the expression that checks that the response credit rating is greater than zero is evaluated first. Table 12-11 describes the assertion behavior.
Table 12-11 Assertion Behavior
If The Credit Rating For The Returned Response Is... | Then... |
---|---|
Less than zero |
The |
Greater than or equal to zero |
The assertion is correct and the second assertion is evaluated. |
Less than 600 |
The |
Greater than or equal to 600 |
The assertion is correct and no fault is thrown from the invoke activity. |
Any number of assertions can be nested. For no fault to be thrown from the activity, all assertions specified must evaluate to true.
This construct enables you to apply multiple levels of validation on an incoming payload, similar to if...else
if...else
statements in Java.
To enable a fault to always be thrown regardless of validation logic, the assertion expression can be specified as false()
. This is similar to the else
construct in Java.
12.14.4.4 Use of Built-in and Custom XPath Functions and $variable References
You can also use built-in and custom XPath functions and $variable
references within the assertion condition. The following code provides several examples.
<bpelx:postAssert expression="bpws:getVariableData( 'crOutput', 'payload', '/tns:rating' ) > 0" ... /> <bpelx:postAssert expression="custom:validateRating()" ... /> <bpelx:postAssert xmlns:fn='http://www.w3.org/2005/xpath-functions' expression="fn:false()" ... />
If an error is thrown by the XPath expression evaluation, the error is wrapped with a BPEL fault and thrown from the activity.
Faults that are thrown from a request-response invoke activity, receive activity, or onMessage branch of a pick or scope activity because of a failed assertion evaluation can be caught and handled by BPEL's fault management framework. For information, see Handling Faults with the Fault Management Framework.
Faults that are not caught and handled within a BPEL process flow are thrown from a BPEL component if the component WSDL declares the fault on the operation. If the fault is not declared on the operation, the fault is converted into a FabricInvocationException
, which is a runtime fault. This fault can be caught by any caller components (including BPEL components), but the fault type is no longer the one originally thrown (however, the fault message string still retains traces of the original fault message).
For more information about runtime faults, see Introduction to the Business and Runtime Fault Categories of BPEL Faults.
For more information about fault policies, see Handling Faults with the Fault Management Framework.
12.14.4.5 Assertion Condition Evaluation Logging of Events to the Instance Audit Trail
Each assertion condition that is evaluated causes an event to be logged to the instance audit trail. The event indicates whether the assertion passed or failed (for failure, the fault name and message are printed). The event also includes the name
attribute specified in the assertion element. If no name
attribute is provided, the line number of the assertion element in the BPEL process flow is used. The assertion condition printed in the audit event helps identify the assertion and better enables debugging of the flow.
12.14.4.6 Expressions Not Evaluating to an XML Schema Boolean Type Throw a Fault
If the assertion condition XPath expression does not evaluate to an XML schema boolean type, a bpelx:postAssertFailure
fault is thrown from the activity. An event in the instance audit trail is also logged indicating the error. The following example provides details:
<bpelx:postAssert expression="bpws:getVariableData( 'crOutput', 'payload', '/tns:rating' ) > 0" ... /> <bpelx:postAssert expression="custom:validateRating()" ... /> <bpelx:postAssert xmlns:fn='http://www.w3.org/2005/xpath-functions' expression="fn:false()" ... />
Analysis of the assertion expression is performed by the BPEL compiler and errors are reported if an expression does not evaluate to an XML schema boolean type. For custom XPath functions, this type of analysis is not performed.
12.14.4.7 Assertion Conditions in a Standalone Assert Activity
You can also create assertion conditions in a standalone assert activity in a BPEL process service component. The assertion specifies an XPath expression that, when evaluated to false, causes a BPEL fault to be thrown from the activity.
The bpelx:assert
extension implements assertions in the standalone assert activity:
<bpelx:assert name="Assert1" expression="string" message="string"/>
For information about using the standalone assert activity, see How to Create Assertion Conditions.
12.14.5 What You May Need to Know About Postassertion and Preassertion Condition Schemas and Syntax
The assertion condition is specified as a nested extension element. The following example shows the postassertion condition schema definition in BPEL 2.0.
<invoke | receive | onMessage> standard-elements <bpelx:postAsserts> <bpelx:postAssert faultName="QName"> <bpelx:expression expressionLanguage="anyURI"?>expression </bpelx:expression> <bpelx:message expressionLanguage="anyURI"?>expression</bpelx:message> </bpelx:postAssert> </bpelx:postAsserts> </invoke | receive | onMessage>
The following example shows the postassertion condition syntax in BPEL 2.0.
<bpelx:postAsserts> <bpelx:postAssert faultName="ns2:InvalidInput"> <bpelx:expression>number(concat($inputVariable.payload/client:input,'2')) < 500</bpelx:expression> <bpelx:message>"AssertXpathPostInvoke_20 assert fired"</bpelx:message> </bpelx:postAssert> </bpelx:postAsserts>
The following example shows the postassertion condition schema definition in BPEL 1.1. Note the differences between BPEL 1.1 and BPEL 2.0.
<invoke | receive | onMessage> standard-elements <bpelx:postAssert name="ncname" expression="boolean-expr" faultName="QName"+ message="generic-expr"+/> </invoke | receive | onMessage>
The following example shows the postassertion condition syntax in BPEL 1.1.
<bpelx:postAssert name="Assert_1" message='Post Invoke Multiple assert value fired' faultName="ns2:NegativeValue" expression="bpws:getVariableData('invar','payload','/ns1:process/ns1:input') > 0"/>
The following example shows the preassertion condition schema definition in BPEL 2.0.
<invoke | reply> standard-elements <bpelx:preAsserts> <bpelx:preAssert faultName="QName"> <bpelx:expression expressionLanguage="anyURI"?>expression</bpelx:expression> <bpelx:message expressionLanguage="anyURI"?>expression</bpelx:message> </bpelx:preAssert> </bpelx:preAsserts> </invoke | reply>
The following example shows the preassertion condition syntax in BPEL 2.0.
<bpelx:preAsserts> <bpelx:preAssert faultName="ns1:InvalidInput"> <bpelx:expression>concat($inputVariable.payload/client:input,'2') > $inputVariable.payload/client:input</bpelx:expression> <bpelx:message>"AssertXpathPreInvoke_20 Assert test"</bpelx:message> </bpelx:preAssert> </bpelx:preAsserts>
The following example shows the preassertion condition schema definition in BPEL 1.1. Note the differences between BPEL 1.1 and BPEL 2.0.
<invoke | reply> standard-elements <bpelx:preAssert name="NCName" expression="string" message="string" faultName="QName"/> </invoke | reply>
The following example shows the preassertion condition syntax in BPEL 1.1.
<bpelx:preAssert name="Assert_1" expression="bpws:getVariableData('invar','payload','/ns1:process/ns1:input') > 0" message='pre invoke assert NegativeInput fired' faultName="ns4:NegativeInput"/>
The bpelx:postAssert
extension specifies the XPath expression to evaluate upon receipt of a callback message from a partner. If the assertion expression returns a false boolean value, the specified fault is thrown from the activity. If the assertion expression returns a true boolean value, no fault is thrown and the activities following the invoke activity, receive activity, or the onMessage branch of pick and scope activities are executed as in a normal BPEL process flow.
The bpelx:preAssert
or bpelx:postAssert
extension is similar to the Java assert
statement. In Java, if the assert
expression does not evaluate to true, an error is reported by the JVM. Similarly, the expression in the bpelx:preAssert
or bpelx:postAssert
extension must evaluate to true; otherwise, the specified fault is thrown.
For example, with the BPEL 1.1 invoke activity shown in the following example, if the XPath expression specified in the assertion condition returns false, the NegativeCredit
fault is thrown.
<scope> <faultHandlers> <catch faultName="services:NegativeCredit" faultVariable="crError"> <empty/> </catch> </faultHandlers> <sequence> <invoke name="invokeCR" partnerLink="creditRatingService" portType="services:CreditRatingService" operation="process" inputVariable="crInput" outputVariable="crOutput"> <bpelx:postAssert name="negativeCredit" expression="$crOutput.payload/tns:rating > 0" faultName="services:NegativeCredit" message="'Negative Credit'" /> </invoke> </sequence> </scope>
The optional name
attribute for bpelx:preAssert
or bpelx:postAssert
is used while creating the audit trail event message. The name in this instance enables you to identify the assertion element in case multiple assertions are specified. If no name
attribute is specified, the line number of the assertion element in the BPEL file may be used.
12.15 Classifying SOAP Faults as Retriable
Starting with 12c, all web service SOAP faults are not automatically retried based on the fault code returned from the external service. SOAP faults are now retried only when the fault code is classified as server-related (also known as receiver-related). Fault codes classified as client-related do not result in retries. This differs from 11g Release 1 (11.1.1.x), in which Oracle SOA Suite retried all SOAP faults regardless of their fault code (all faults returned were converted to a bpelx:remoteFault
in BPEL, which was retriable).
In 12c when a fault occurs in a reference binding component, the fault code is returned to a BPEL process. The fault is retried based on the setting in the fault code. This is beneficial because you may want to retry the fault only under specific circumstances (such as a system downtime issue). For all other fault occurrences (such as incorrect input), you may not want a retry to occur. In fact, retries on all SOAP faults can delay the processing of legitimate messages.
As described in the Simple Object Access Protocol (SOAP) 1.1 specification at http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383510
, a fault can have a code of server (also known as receiver) or client. The classification of faults determines whether the faults are retriable.
-
Server
Server errors indicate that the message cannot be processed for reasons not directly related to the message contents, but rather to the processing of the message. For example, processing can include communicating with a server that did not respond. The message may succeed at a later time. This is defined as a retriable fault.
-
Client
Client errors indicate that the message was incorrectly formed or did not contain the appropriate information to succeed. For example, the message may lack the proper authentication or payment information. This typically indicates that the message must first be changed before being resent. This is defined as a nonretriable fault.
This fault classification information is propagated into a FabricInvocationException
error. For fault codes classified as client-related, the retryType
flag within this exception is set to NO_RETRY
.
If necessary, you can still invoke a retry on every fault. Set the binding.ws
property oracle.soa.always.retry.on.fault
to true
in the composite.xml
file. This enables Oracle SOA Suite to always retry on any SOAP faults regardless of the fault code.
<reference name="myreference" . . . <binding.ws port=". . . ." location=". . ." <property name="oracle.soa.always.retry.on.fault">true</property> </binding.ws>
Use the following code snippet in composite.xml
to enable custom headers defined at SOA to reach the OSB webservice.
<reference name="RecHttpOSB" ...> ... <binding.ws ... soapVersion="1.1"> <property name="oracle.webservices.http.headers">OSBCustomHttp</property> </binding.ws> </reference>