Monday, March 10, 2008

BPEL Fault Policies; best practise

Introduction
Apart of the fault handling within the BPEL processes itself, a new feature is available in BPEL. This is called the fault handling. Previous the fault must all be handled within each process. An article on this is written in:

OraBPEL Technote #7

The new feature is documented in the release note of Oracle BPEL 10.1.3.3, in the chapter "Fault Management Framework".

BPEL 10.1.3.3 Release notes

Another nice article on BPEL fault handling with an example is written here.

Fault Business Rules
The fault policy is implemented for all the BPEL processes based on the following rules:
  • Existing exception handling in the BPEL processes will be implemented as defined in the standards for that application.
  • A distinction will be made in fault policies for synchronous and a-synchronous policies.
  • The policies will be implemented at Oracle BPEL Process level.
  • The default fault policy, valid for all BPEL processes, will be implemented as if there was no fault policy.
Fault Policies

DefaultFaultPolicy

The default policy will catch all faults message and pass it back to the process that raises the fault. This is defined as follows:
  DefaultPolicy.xml
=============
<?xml version="1.0" encoding="UTF-8"?>
<faultPolicy
version="2.0.1"
id="DefaultPolicy"
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">
<!--
This section describes default conditions.
Build more conditions with faultName, test and action
-->
<!--
CONDITIONS
-->
<Conditions>
<faultName>
<condition>
<action ref="ora-rethrow-fault"/>
</condition>
</faultName>
</Conditions>
<!--
ACTIONS
-->
<Actions>
<!--
This is an action will bubble up the fault
-->
<Action id="ora-rethrow-fault">
<rethrowFault/>
</Action>
</Actions>
</faultPolicy>

The DefaultPolicy.xml file should be created in the following directory
  $ORACLE_HOME/domain/<domain-name>/config/fault-policies
For example
  $ORACLE_HOME/domain/default/config/fault-policies
The bind the DefaultPolicy.xml file as default fault policy handler. The following file must be created and filled with the following content:
  $ORACLE_HOME/domain/<domain-name>/config/fault-bindings.xml
For example

$ORACLE_HOME/domain/default/config/fault-bindings.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">
<!--
DefaultPolicy is defined
in ./fault-policies/DefaultPolicy.xml
-->
<process faultPolicy="DefaultPolicy"/>
<partnerLink faultPolicy="DefaultPolicy"/>
</faultPolicyBindings>
FaultPolicySynchronous
The fault policy for synchronous process is as follows. When a binding or remote fault occurs, it will retry calling this invoke/partnerlink again. It will retry this 5 times with an interval of 4 seconds. This means that if after 20 seconds the retry was still failing, it executes a re-thrown. Meaning that the fault is passed back to the process. The process van now handle the fault in his normal exception handling.

FaultPolicySynchronous.xml
==========================
<?xml version="1.0" encoding="UTF-8"?>
<faultPolicy
version="2.0.1"
id="FaultPolicySynchronous"
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">
<!--
This section describes fault conditions.
Build more conditions with faultName, test and action
-->
<!--
CONDITIONS
-->
<Conditions>
<!--
Fault if wsdlRuntimeLocation is not reachable
-->
<faultName
xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
name="bpelx:remoteFault">
<condition>
<action ref="ora-retry"/>
</condition>
</faultName>
<!--
Fault if location port is not reachable
-->
<faultName
xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
name="bpelx:bindingFault">
<condition>
<action ref="ora-retry"/>
</condition>
</faultName>
</Conditions>
<!--
ACTIONS
-->
<Actions>
<!--
This action will attempt 5 retries with intervals of 4 seconds
retry after 4, 8, 12, 16, 20 seconds
-->
<Action id="ora-retry">
<retry>
<retryCount>5</retryCount>
<retryInterval>4</retryInterval>
<retryFailureAction ref="ora-rethrow-fault"/>
</retry>
</Action>
<!--
This is an action will cause a replay scope fault
-->
<Action id="ora-replay-scope">
<replayScope/>
</Action>
<!--
This is an action will bubble up the fault
-->
<Action id="ora-rethrow-fault">
<rethrowFault/>
</Action>
<!--
This is an action will mark the work item
to be "pending recovery from console"
-->
<Action id="ora-human-intervention">
<humanIntervention/>
</Action>
<!--
This action will cause the instance to terminate
-->
<Action id="ora-terminate">
<abort/>
</Action>
</Actions>
</faultPolicy>

Copy the FaultPolicySynchronous.xml into the $ORACLE_HOME/bpel/domains/<domain-name>/config/fault-policies directory.

FaultPolicyASynchronous
The fault policy for a-synchronous process is as follows. When a binding or remote fault occurs, it will retry calling this invoke/partner link again. It will retry this 10 times with an interval of 2 seconds, growing exceptional. This means that 9 attempts with increased intervals of 2 seconds, it retries after 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 seconds, this will result in a duration of 2046 seconds; approx 34 minutes.

If after 34 minutes the retry was still failing, it executes a human-intervention. Meaning that the fault is waiting for human input. In the Oracle BPEL Console, on the activation tab, the processes is waiting on an action of the administrator.
  FaultPolicyASynchronous.xml
==========================
<?xml version="1.0" encoding="UTF-8"?>
<faultPolicy
version="2.0.1"
id="FaultPolicyASynchronous"
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">
<!--
This section describes fault conditions.
Build more conditions with faultName, test and action
-->
<!--
CONDITIONS
-->
<Conditions>
<!--
Fault if wsdlRuntimeLocation is not reachable
-->
<faultName
xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
name="bpelx:remoteFault">
<condition>
<action ref="ora-retry"/>
</condition>
</faultName>
<!--
Fault if location port is not reachable
-->
<faultName
xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
name="bpelx:bindingFault">
<condition>
<action ref="ora-retry"/>
</condition>
</faultName>
</Conditions>
<!--
ACTIONS
-->
<Actions>
<!--
This action will attempt 9 retries with increased intervals of 2 seconds
retry after 2, 4, 8, 16, 32, 64, 128, 256, 512 seconds,
this will result in a duration of 1022 seconds; approx 17 minutes
-->
<Action id="ora-retry">
<retry>
<retryCount>9</retryCount>
<retryInterval>2</retryInterval>
<exponentialBackoff/>
<retryFailureAction ref="ora-human-intervention"/>
</retry>
</Action>
<!--
This is an action will cause a replay scope fault
-->
<Action id="ora-replay-scope">
<replayScope/>
</Action>
<!--
This is an action will bubble up the fault
-->
<Action id="ora-rethrow-fault">
<rethrowFault/>
</Action>
<!--
This is an action will mark the work item to be "pending recovery from console"
-->
<Action id="ora-human-intervention">
<humanIntervention/>
</Action>
<!--
This action will cause the instance to terminate
-->
<Action id="ora-terminate">
<abort/>
</Action>
</Actions>
</faultPolicy>
Copy the FaultPolicyASynchronous.xml into the $ORACLE_HOME/bpel/domains/<domain-name>/config/fault-policies directory.

Implementation
The fault policies are read during startup of the Oracle BPEL PM. This means that new fault policies or policies that are changed can only be made available by restarting the BPEL PM.

All processes should be aware of the new fault policy mechanism. This means that synchronous process should use the "FaultPolicySynchronous" policy. A-Synchronous process should use the "FaultPolicyASynchronous" policy.

To implement the fault policy in a BPEL process, add the following lines in the BPEL.XML file for each process, just before the "</BPELProcess>" tag:

Synchronous processes:
  <faultPolicyBindings>
<process faultPolicy="FaultPolicySynchronous"/>
</faultPolicyBindings>
A-Synchronous processes:
  <faultPolicyBindings>
<process faultPolicy="FaultPolicyASynchronous"/>
</faultPolicyBindings>

Post a Comment