Fault handling allows a BPEL process service component to handle error messages or other exceptions returned by outside web services, and to generate error messages in response to business or runtime faults. You can also define a fault management framework to catch faults and perform user-specified actions defined in a fault policy file.
12.1 Introduction to a Fault Handler
Fault handlers define how the BPEL process service component responds when the web 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.provides an example of how a fault handler sets a credit rating variable to
-1000
.The code segment in Example 12-1 defines the fault handler for this operation in the BPEL file:
Example 12-1 Fault Handler Definition
<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>
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
The Business Process Execution Language for Web Services Specification defines the following standard faults in the namespace ofhttp://schemas.xmlsoap.org/ws/2003/03/business-process/
:-
bindingFault
-
conflictingReceive
-
conflictingRequest
-
correlationViolation
-
forcedTermination
-
invalidReply
-
joinFailure
-
mismatchedAssignmentFailure
-
remoteFault
-
repeatedCompensation
-
selectionFailure
-
uninitializedVariable
-
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.3 Introduction to Categories of BPEL Faults
A BPEL fault has a fault name called aQname
(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. ThemessageType
, if applicable, is defined in the WSDL. 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 if 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, and so on.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 Example 12-2 defines the messageType
:
Example 12-2 messageType Definition
<?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>
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
AbindingFault
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 retryable. This type of fault usually must be fixed by human intervention.12.3.2.2 remoteFault
AremoteFault
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.4 Using 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 activity. 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 Console. 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 fault policy).
-
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 process and Oracle Mediator service components
composite.xml
file of the SOA composite application or in a remote location identified by two properties that you set.
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. -
SOA composite applications
-
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. Example 12-3 provides details about these two properties. In this example, the fault policy files are placed into the SOA Metadata Service (MDS) shared area.
-
In the same directory as the
12.4.1 How to Design a Fault Policy
This section describes how to design a fault policy.
Note:
The Facades API enables you to programmatically perform the abort, retry
(with a success action), continue, rethrow, and replay recovery
options.12.4.1.1 Understanding How 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.
For example, assume an invoke activity faults with
faultname="abc"
. There is a policy binding specified in the fault-binding.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
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
-
First match the resolve binding (in this case,
policy-id-2
).
-
If the fault resolution fails, go to the next possible match (
policy-id-4
).
-
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.1.2 Creating a Fault Policy File for Automated Fault Recovery
-
Create a fault policy file (for example, named
fault-policies.xml
). This file includescondition
andaction
sections for performing specific tasks.
-
Place the file in the same directory as the
composite.xml
file or place it in a different location and define theoracle.composite.faultPolicyFile
property. Example 12-4 provides details.
-
Define the
condition
section of the fault policy file.
-
Note the following details about the
condition
section:
-
This section provides a condition based on
faultName
.
-
Multiple conditions may be configured for a
faultName
.
-
Each condition has one
test
section (an XPath expression) and oneaction
section.
-
The
test
section (XPath expression) is evaluated for the fault variable available in the fault.
-
The
action
section has a reference to the action defined in the same file.
-
You can only query the fault variable available in the fault.
-
The order of condition evaluation is determined by the sequential order in the document.
condition
section use in the fault policy file. All actions defined in thecondition
section must be associated with an action in theaction
section.
Table 12-1 Use of the condition Section in the Fault Policy FileCondition Example Fault Policy File Syntax This condition is checking a fault variable for code = "WSDLFailure"
Anaction
ofora-terminate
is specified.<condition> <test>$fault.code="WSDLReading Error" </test> <action ref="ora-terminate"/> </condition>
No test
condition is provided. This is a catch all condition for a givenfaultName
.<condition> <action ref="ora-rethrow"/> </condition>
If the faultName
name attribute is missing, this indicates a catch all activity for faults that have anyQName
.<faultName > . . . </faultName>
-
This section provides a condition based on
-
Note the following details about the
-
Define the
action
section of the fault policy file. Note that validation of fault policy files is done during deployment. If you change the fault policy, you must redeploy the SOA composite application that includes the fault policy.
Table 12-2 provides several examples ofaction
section use in the fault policy file. You can provide automated recovery actions for some faults. In all recovery actions except retry and human intervention, the framework performs the actions synchronously.
Table 12-2 Use of action Section in the Fault Policy FileRecovery Actions Fault Policy File Syntax Retry: Provides the following actions for retrying the activity.
-
Retry a specified number of times.
-
Provide a delay between retries (in seconds).
-
Increase the interval with an exponential back off.
-
Chain to a retry failure action if retry N times fails.
-
Chain to a retry success action if a retry is successful.
2
x the delay, where delay is the current retry interval. For example, if the current retry interval is2
seconds, the next retry attempt is scheduled at4
, the next at8
, and the next at16
seconds until theretryCount
value is reached.<Action id="ora-retry"> <Retry> <retryCount>3</retryCount> <retryInterval>2</retryInterval> <exponentialBackoff/> <retryFailureAction ref="ora-java"/> <retrySuccessAction ref="ora-java"/> </Retry> </Action>
Note the following details:
-
The framework chains to the retry success action if the retry attempt is successful.
-
If all retry attempts fail, the framework chains to the retry failure action.
Human Intervention: Causes the current activity to stop processing. You can now go to Oracle Enterprise Manager Fusion Middleware Control Console and perform manual recovery actions on this instance. <Action id="ora-human-intervention"> <humanIntervention/></Action>
Terminate Process: Terminates the process <Action id="ora-terminate"><abort/></Action>
Java Code: Enables you to execute an external Java class.
returnValue
: The implemented Java class must implement a method that returns a string. The policy can chain to a new action based on the returned string.
For additional information, see Section 12.4.3, "How to Use a Java Action Fault Policy"<Action id="ora-java"> <!-- this is user provided custom java class--> <javaAction className="mypackage.myClass" defaultAction="ora-terminate"> <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>
Rethrow Fault: The framework sends the fault to the BPEL fault handlers (catch activities in scope activities). If none are available, the fault is sent up. <Action id="ora-rethrow-fault"><rethrowFault/></Action>
Replay Scope: Raises a replay fault. <Action id="ora-replay-scope"><replayScope/></Action>
-
Retry a specified number of times.
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.condition
and action
sections.
Notes:
-
Fault policy file names are not restricted to one specific name. However, they must conform to the
fault-policy.xsd
schema file.
-
Example 12-5 provides an example of catching faults based on fault names. You can also catch faults based on message types, or on both:
<fault 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="0.0.1" id="FusionMidFaults" 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 xmlns:medns="http://schemas.oracle.com/mediator/faults" name="medns:mediatorFault"> <condition> <action ref="MediatorJavaAction"/> </condition> </faultName> <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:remoteFault"> <condition> <action ref="BPELJavaAction"/> </condition> </faultName> <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:bindingFault"> <condition> <action ref="BPELJavaAction"/> </condition> </faultName> <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:runtimeFault"> <condition> <action ref="BPELJavaAction"/> </condition> </faultName> </Conditions> <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="MediatorJavaAction"> <!-- this is user provided class--> <javaAction className="MediatorJavaAction.myClass" defaultAction="default-terminate"> <returnValue value="MANUAL" ref="default-human-intervention"/> </javaAction> </Action> <Action id="BPELJavaAction"> <!-- this is user provided class--> <javaAction className="BPELJavaAction.myAnotherClass" defaultAction="default-terminate"> <returnValue value="MANUAL" ref="default-human-intervention"/> </javaAction> </Action> </Actions> </faultPolicy> </faultPolicies>
12.4.1.3 Associating a Fault Policy with Fault Policy Binding
Note:
The fault policy file binding file must be named fault-bindings.xml
. This conforms to the fault-bindings.xsd
schema file.-
Create a fault policy binding file (
fault-bindings.xml
) that associates the policies defined in the fault policy file with the level of fault policy binding you are using (either a SOA composite application or a component (reference binding component or BPEL process or Oracle Mediator service component).
-
Place the file in the same directory as the
composite.xml
file or place it in a remote location and define theoracle.composite.faultBindingFile
property as shown in Step 2.
Example 12-6 shows a fault policy bindings file that associates the fault policies defined in thefault-policies.xml
file with theFusionMidFaults
SOA composite application.
Example 12-6 fault-buildings.xml File
<?xml version="1.0" encoding="UTF-8" ?>
<faultPolicyBindings version="0.0.1"
xmlns="http://schemas.oracle.com/bpel/faultpolicy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<composite faultPolicy="FusionMidFaults"/>
<!--<composite faultPolicy="ServiceExceptionFaults"/>-->
<!--<composite faultPolicy="GenericSystemFaults"/>-->
</faultPolicyBindings>
12.4.1.4 Additional Fault Policy and Fault Policy Binding File Samples
This section provides additional samples of fault policy and fault policy binding files. Example 12-7 shows thefault-policies.xml
file contents.
Example 12-7 fault-policies.xml File
<?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">
<!-- we get this fault when SSN starts with 0-->
<condition>
<test>$fault.payload="Bankruptcy Report"</test>
<action ref="ora-human-intervention"/>
<!--action ref="ora-retry"/-->
</condition>
<!-- we get this fault when SSN starts with 1-->
<condition>
<test>$fault.payload="Bankruptcy Report-abort"</test>
<action ref="ora-terminate"/>
</condition>
<!-- we get this fault when SSN starts with 2-->
<condition>
<test>$fault.payload="Bankruptcy Report-rethrow"</test>
<action ref="ora-rethrow-fault"/>
</condition>
<!-- we get this fault when SSN starts with 3-->
<condition>
<test>$fault.payload="Bankruptcy Report-replay"</test>
<action ref="ora-replay-scope"/>
</condition>
<!-- we 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>
<!-- we 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>
fault-buildings.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.1.5 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 Example 12-9. In this case, only the first rejection handler defined (for this example,ora-queue
) is executed.
Example 12-9 Fault Policy with Multiple Rejection Handlers
<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.2 How to Execute a Fault Policy
You deploy a fault policy as part of a SOA composite application. After deployment, you can perform the following fault recovery actions from Oracle Enterprise Manager Fusion Middleware Control Console:-
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
-
Instructions on executing a fault policy in Oracle Enterprise Manager Fusion Middleware Control Console
-
Use cases in which you define a fault policy that uses human intervention
12.4.3 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 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 Example 12-10.
Example 12-10 Java Action Fault Policy
<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>
ReturnValue
use.
Table 12-3 System Interpretation of Java Action Fault Policy
Code | Description |
---|---|
<ReturnValue value="RETRY" ref="ora-retry"/> |
Execute the ora-retry action if the method returns a string of RETRY . |
<ReturnValue value="” ref=”ora-rethrow”/> |
Fails in validation. |
<JavaAction ClassName="mypackage.myclass" defaultAction="ora-human-intervention"> |
Execute ora-human-intervention after Java code execution. This attribute is used if the return from the method does not match any provided ReturnValue . |
<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. |
IFaultRecoveryJavaClass
interface. This interface has two methods, as shown in Example 12-11.
Example 12-11 implementation of IFaultRecoveryJavaClass
public interface IFaultRecoveryJavaClass { public void handleRetrySuccess( IFaultRecoveryContext ctx ); public String handleFault( IFaultRecoveryContext ctx ); }
-
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
.
IFaultRecoveryContext
:
Example 12-12 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(); }
Example 12-13 Service Engine Implementation of IFaultRecoveryContext
public class BPELFaultRecoveryContextImpl extends BPELXExecLetUtil implements IBPELFaultRecoveryContext, IFaultRecoveryContext{ ... }
IBPELFaultRecoveryContext
, as shown in Example 12-14.
Example 12-14 Oracle BPEL Process Manager-Specific Data
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; }
javaAction
implementation.
Example 12-15 Implementation of a javaAction
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.4 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 theora-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 Console.
-
Configure an
ora-terminate
action to close the instance (mark it asclosed.faulted
) and never retry again.
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 following fault policy file 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
-
A detailed fault error message is logged in the audit trail
-
Recovery may also fail. In that case, the invoke activity is re-executed. Additional audit messages are logged.
12.4.5 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-2:You specify the following retry parameters 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 following actions:
<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)
-
JCA retry 1 (with
-
Fault policy retry 2:
-
JCA retry 1 (with
2
seconds interval)
-
JCA retry 2 (with
4
seconds interval)
-
JCA retry 1 (with
-
Fault policy retry 3:
-
JCA retry 1 (with
2
seconds interval)
-
JCA retry 2 (with
4
seconds interval)
-
JCA retry 1 (with
12.5 Catching BPEL Runtime Faults
BPEL runtime faults can be caught as a named BPEL fault. ThebindingFault
and remoteFault
can be associated with a message. This action enables the faultHandler
to get details about the faults.12.5.1 How to Catch BPEL Runtime Faults
The following procedure shows how to use the provided examples to generate a fault and define a fault handler to catch it. In this case, you modify a WSDL file to generate a fault, and create a catch attribute to catch it.
To catch BPEL runtime faults:
-
Import
RuntimeFault.wsdl
into your process WSDL.RuntimeFault.wsdl
is seeded into the MDS fromsoa.mar
insidesoa-infra-wls.ear
during its deployment.You may see a copy ofsoa.mar
in the deployed SOA Infrastructure in the Oracle WebLogic Server domain, which is a JAR/ZIP file containingRuntimeFault.wsdl
.
-
Declare a variable with
messageType bpelx:RuntimeFaultMessage
.
-
Catch it using the following syntax:
<catch faultName="bpelx:remoteFault" | "bpelx:bindingFault" faultName="varName">
12.6 Getting Fault Details with the getFaultAsString XPath Extension Function
ThecatchAll
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.7 Throwing Internal Faults
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. If you add a throw activity to your BPEL process service component, it automatically includes a copy rule that copies the fault name and type into the output payload. 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.12.7.1 How to Create a Throw Activity
To create a throw activity:
-
From the Component Palette, drag a Throw activity into the designer.
-
Double-click and define the Throw activity.
-
Optionally enter a name or accept the default value.
-
To the right of the Namespace URI field, click the Search icon to select the fault to monitor.
-
Select the fault in the Fault Chooser dialog, and click OK.
The namespace URI for the selected fault displays in the Namespace URI field. Your fault selection also automatically displays in the Local Part field.
Figure 12-3 provides an example of a completed Throw dialog. This example shows the Throw_Fault_CC_Denied throw activity of the Scope_AuthorizeCreditCard scope activity in the WebLogic Fusion Order Demo application. This activity throws a fault for orders that are not approved.
-
Click OK.
12.8 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.8.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 Example 12-18:
Example 12-18 Reply Activity
<reply partnerlinke="partner-link-name" portType="port-type-name" operation="operation-name" variable="variable-name" (optional) faultName="fault-name"> </reply>
For more information, see the following chapters:
-
Chapter 11, "Using Conditional Branching in a BPEL Process" for setting up the conditional structure
-
Chapter 8, "Invoking a Synchronous Web Service from a BPEL Process" for synchronous interactions
12.8.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 Chapter 9, "Invoking an Asynchronous Web Service from a BPEL Process."
12.9 Using a Scope Activity to Manage a Group of Activities
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 allows you to collapse them into what appears to be a single element in Oracle BPEL Designer.Example 12-19 shows a scope named
Scope_FulfillOrder
from the WebLogic Fusion Order Demo application. This scope invokes the FulfillOrder
mediator component, which determines the shipping method for the order.
Example 12-19 Scope Activity
<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.9.1 How to Create a Scope Activity
To create a scope activity:
-
From the Component Palette, drag a Scope activity into the designer.
-
Open the scope activity by double-clicking it or by single-clicking the Expand icon.
-
From the Component Palette, drag and define activities to build the functionality within the scope.
-
Click OK.
When complete, scope activity design can look as shown in . This example shows the Scope_AuthorizeCreditCard scope activity of the WebLogic Fusion Order Demo application.
12.9.2 What Happens After You Create a Scope Activity
Example 12-20 shows the throw 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 it 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.
Example 12-20 Scope Activity
<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.9.3 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 be used to make large BPEL flows more readable.12.9.4 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, contain 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.
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.12.9.5 How to Create a Catch Activity
To create a catch activity:
-
In the expanded Scope activity, click Add Catch Branch.
This creates a catch activity in the right side of the scope activity.
-
Double-click the Catch activity.
-
Optionally enter a name.
-
To the right of the Namespace URI field, click the Search icon to select the fault.
-
Select the fault in the Fault Chooser dialog, and click OK.
The namespace URI for the selected fault displays in the Namespace URI field. Your fault selection also automatically displays in the Local Part field.
Figure 12-7 provides an example of a Catch dialog. This example shows the selectionFailure catch activity of the Scope_AuthorizeCreditCard scope activity in the WebLogic Fusion Order Demo application. This catch activity catches orders in which the credit card number is not provided.
-
Design additional fault handling functionality.
-
Click OK.
Figure 12-8 provides an example of two catch activities for the Scope_AuthorizeCreditCard scope activity. The second catch activity catches credit types that are not valid.
12.9.6 What Happens When You Create a Catch Branch
Figure 12-8 shows thecatch
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.
Example 12-22 Catch Branch
<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>
12.9.7 How to Create an Empty Activity to Insert No-Op Instructions into a Business Process
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:
-
From the Component Palette, drag an Empty activity into the designer.
-
Double-click the Empty activity.
The Empty dialog appears, as shown in Figure 12-9.
-
Optionally enter a name.
-
Click OK.
12.9.8 What Happens When You Create an Empty Activity
The syntax for anempty
activity is shown in Example 12-23.If no
catch
or catchAll
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 Section 12.11, "Using the Terminate Activity to Stop a Business Process Instance") had been performed.12.10 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.12.10.1 How to Use Compensation After Undoing a Series of Operations
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 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 compensation is to be performed.
-
In the compensation handler of the scope that immediately encloses the scope for which compensation is to be performed.
<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 a compensation for such a scope nested within the outer scope disables the availability of default-order compensation.
12.10.2 How to Create a Compensate Activity
To create a compensate activity:
-
From the Component Palette, drag an Compensate activity into the designer.
-
Double-click the Compensate activity.
-
Select a scope activity in which to invoke the compensation handler.
-
Click OK.
12.11 Using the Terminate Activity to Stop a Business Process Instance
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.11.1 How to Create a Terminate Activity
To create a terminate activity:
-
From the Component Palette in Oracle JDeveloper, drag a Terminate activity into the designer. Figure 12-11 provides an example.
-
Double-click the terminate activity.
-
Optionally enter a name.
-
Click OK.
12.11.2 What Happens When You Create a Terminate Activity
The syntax for theterminate
activity is shown in Example 12-25. This stops the business process instance.
No comments:
Post a Comment
Note: only a member of this blog may post a comment.