Sie sind auf Seite 1von 20

Oracle BPEL 10.1.3.

3 Fault Policy Management

Faults
In bpel-processes we can categorize the faults into: business faults and runtime faults. Business faults
are application specific faults and will occur when we use the “throw”-activity or if we invoke a
partnerlink which returns with some fault. It’s up to the “business” to decide what needs to be done
when the fault occurs and what activities are needed for handling it.
Besides the business faults we have the runtime faults. Runtime faults will not be defined by the user,
so we need to design parts in the process to handle them. In bpel we will make use of the catch-activity
for this. In the catch itself we can invoke our own fault-handling processes or do some other activities
(retry etc) which are needed to get a valid situation again.
Oracle made a nice technote for some good information about all the possible faults and some extra
faults defined by Oracle Process Manager.

Framework
In the good old days (before patch 10.1.3.3) we needed to design the fault-handling part for every bpel-
process.
Possibilities were there by making use of for example some Error Hospital, but still, every process
individually needed changes for being able to handle faults.
With the latest patch for the Oracle Soa Suite (10.1.3.3) , Oracle provided a new Fault Management
framework. This framework will gives us the opportunity to handle all the business and runtime faults
for an “invoke” activity. With the framework we can define 1 policy for every bpel domain.
In a so called “fault-binding” (/bpel/domains/default/config/fault-policy-binding.xml) , we can setup
which policies we’re going to use and which processes/partnerlinks/porttypes will be part of it. The
framework will use the binding in order of the following priority :
• bpel.xml
• policy defined on the server
In a so called “fault-policy” (/bpel/domains/default/config/fault-policies/DefaultPolicy.xml), we can
define what type of faults we want to catch and what actions need to get executed.
If there is already some fault-handling (catch) defined in the the bpel process, the framework will
overrule this, and use a policy if possible.

fault-policy-binding
The fault-bindings will be defined on the next location : /bpel/domains/default/config/fault-policy-
binding.xml
The xsd-schema for the fault-bindings can be found on this location : /bpel/system/xmllib/fault-policy-
binding.xsd
view source
print?
01 < ?xml version="1.0" encoding="UTF-8"?>
02 <faultpolicybindings version="2.0.1"
03 xmlns="http://schemas.oracle.com/bpel/faultpolicy"
04 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- Enabling this will cause all processes in this domain to
05
use this
06 fault policy
07 <process faultPolicy="DefaultPolicy"/>
08 -->
<!-- DefaultPolicy is defined in ./fault-
09
policies/DefaultPolicy.xml -->
10 <partnerlink faultPolicy="DefaultPolicy">
<!-- Enabling this will cause all invoke faults at partner
11
link
12 name of "creditRatingService" to use fault policy with
13 id id = DefaultPolicy
14 <name>creditRatingService
15 -->
<!-- all invoke faults at partner link below port type use
16
fault policy
17 with id = DefaultPolicy
The following entry covers the
18
samples/tutorials/122.DBAdapter/InsertWithCatch sample. -->
<porttype
19 xmlns:db="http://xmlns.oracle.com/pcbpel/adapter/db/insert/">db:insert_plt</portty
pe>
20 </partnerlink>
21 </faultpolicybindings>
In the policy we can define on several levels
(process,partnerLink,portType) if we want to make use of a policy. In
the comment of the xml you will see what needs to be turned on or off
to apply to policy.

fault-policies
The fault-policies will be defined on the next location : /bpel/domains/default/config/fault-policies. The
xsd-schema for the fault-policies can be found on this location : /bpel/system/xmllib/fault-policy.xsd.
Oracle delivers the following policy by default.
view source
print?
01 < ?xml version="1.0" encoding="UTF-8"?>
02 <faultpolicy version="2.0.1" id="DefaultPolicy"
03 xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
04 xmlns:xs="http://www.w3.org/2001/XMLSchema"
05 xmlns="http://schemas.oracle.com/bpel/faultpolicy"
06 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- This section describes fault conditions. Build more
07
conditions with faultName, test and action -->
08 <conditions>
09 <!-- Fault if wsdlRuntimeLocation is not reachable -->
<faultname xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
10
name="bpelx:remoteFault">
11 <condition>
12 <action ref="ora-retry"/>
13 </condition>
14 </faultname>
15 <!-- Fault if location port is not reachable-->
<faultname xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
16
name="bpelx:bindingFault">
17 <condition>
18 <action ref="ora-rethrow-fault"/>
19 </condition>
20 </faultname>
21 </conditions>
22 <actions>
<!-- This action will attempt 8 retries at increasing
23
intervals of 2, 4, 8, 16, 32, 64, 128, and 256 seconds. -->
24 <action id="ora-retry">
25 <retry>
26 <retrycount>8</retrycount>
27 <retryinterval>2</retryinterval>
28 <exponentialbackoff />
29 </retry>
30 </action>
31 <!-- This is an action will cause a replay scope fault-->
32 <action id="ora-replay-scope">
33 <replayscope />
34 </action>
35 <!-- This is an action will bubble up the fault-->
36 <action id="ora-rethrow-fault">
37 <rethrowfault />
38 </action>
39 <!-- This is an action will mark the work item to be "pending
recovery from console"-->
40 <action id="ora-human-intervention">
41 <humanintervention />
42 </action>
43 <!-- This action will cause the instance to terminate-->
44 <action id="ora-terminate">
45 <abort />
46 </action>
47 </actions>
48 </faultpolicy>
A policy consists of a conditions-section and an actions-section.
In the conditions-sections we will define which faults need to be
handled and which actions will be executed.
view source
print?
1 <conditions>
2 <!-- Fault if wsdlRuntimeLocation is not reachable -->
<faultname xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
3
name="bpelx:remoteFault">
4 <condition>
5 <action ref="ora-retry"/>
6 </condition>
7 </faultname>
8 </conditions>
In this part of the code the framework will “catch” all remoteFaults
and execute the ora-retry action.
view source
print?
1 <condition>
2 <test>$fault.code/code="INVALID_WSDL"</test>
3 <action ref="ora-terminate"/>
4 </condition>
In this part of the code we will check if the fault-code =
“INVALID_WSDL”. The action to be executed is : ora-terminate.
Oracle delivers a few default actions as part of the framework. At this moment that list isn’t extensible.
If we still need some custom fault-handling we could make use of the ora-java action. This action will
allow us to make us of some custom java, and inhere we will be able to decide what to do with the
fault.
Default available actions :
• ora-retry ( retry the activity )
• ora-replay-scope ( replay the scope in which the fault occurred )
• ora-rethrow-fault ( system will throw the fault to the bpel fault handlers )
• ora-human-intervention ( the current activity will freeze. In the console the user will be able to
take several actions on this
• instance )
• ora-terminate ( terminate instance )
• ora-java ( execute custom java )

Lets practice!
To show how the framework works we will build a little example. We deployed a simpe java
webservice (helloWorld). We also build a little bpel-process with a few steps in it (assign and invoke of
the java service).As part of the error-handling we added a catch on the remoteFault. In the catch we
won’t be doing any fault-handling, just the catch and an assign to the output.
To generate a remoteFault we undeployed the javaservice from the oc4j, and executed the bpel-process
again. After executing again, the process will fall into the catch we defined.
We will not change the structure of the process, and only define a new policy on the server.
First step is to define the fault-binding. fault-bindings.xml:
view source
print?
1 < ?xml version="1.0" encoding="UTF-8"?>
2 <faultpolicybindings version="2.0.1"
3 xmlns="http://schemas.oracle.com/bpel/faultpolicy"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5 <process faultPolicy="BlogTestPolicy"/>
<!-- DefaultPolicy is defined in ./fault-
6
policies/DefaultPolicy.xml -->
7 <partnerlink faultPolicy="BlogTestPolicy"/>
8 </faultpolicybindings>
The policy is named “BlogTestPolicy” and all processes and
partnerlinks will use it.
Next step is to define the policy. BlogTestPolicy.xml:
view source
print?
01 < ?xml version="1.0" encoding="UTF-8"?>
02 <faultpolicy version="2.0.1" id="BlogTestPolicy"
03 xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
04 xmlns:xs="http://www.w3.org/2001/XMLSchema"
05 xmlns="http://schemas.oracle.com/bpel/faultpolicy"
06 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- This section describes fault conditions. Build more
07
conditions with faultName, test and action -->
08 <conditions>
09 <!-- Fault if wsdlRuntimeLocation is not reachable -->
<faultname xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
10
name="bpelx:remoteFault">
11 <condition>
12 <action ref="ora-retry"/>
13 </condition>
14 <condition>
15 <action ref="ora-human-intervention"/>
16 </condition>
17 </faultname>
18 </conditions>
19 <actions>
<!-- This action will attempt 8 retries at increasing
20
intervals of 2, 4, 8, 16, 32, 64, 128, and 256 seconds. -->
21 <action id="ora-retry">
22 <retry>
23 <retrycount>8</retrycount>
24 <retryinterval>2</retryinterval>
25 <exponentialbackoff />
26 </retry>
27 </action>
28 <!-- This is an action will cause a replay scope fault-->
29 <action id="ora-replay-scope">
30 <replayscope />
31 </action>
32 <!-- This is an action will bubble up the fault-->
33 <action id="ora-rethrow-fault">
34 <rethrowfault />
35 </action>
<!-- This is an action will mark the work item to be "pending
36
recovery from console"-->
37 <action id="ora-human-intervention">
38 <humanintervention />
39 </action>
40 <!-- This action will cause the instance to terminate-->
41 <action id="ora-terminate">
42 <abort />
43 </action>
44 </actions>
45 </faultpolicy>
We defined a policy which will handle all remoteFaults. When a
remoteFault occurs, the framework will be able to execute two
actions. First it will do the “ora-retry” action, if the fault still
occurs the next action will be executing the “ora-human-intervention”
action. After creating the policy we restart the oc4j-container to
make sure the policy will be active.
**update
To chain the actions, in this example we just added 2 actions after each other. This won’t work, and
only the last action will get executed. The way to do this is to use the retryFailureAction-element in the
action.
for example :
view source
print?
1 <action id="ora-retry">
2 <retry>
3 <retrycount>5</retrycount>
4 <retryinterval>10</retryinterval>
5 <retryfailureaction ref="ora-human-intervention"/>
6 </retry>
7 </action>
Before we start testing the framework we make sure we still use the
same situation as in the beginning. We have undeployed the
javawebservice which we will invoke in the bpel process. We left the
catch in the process. On the server we defined the policy. This
policy will now handle the remoteFault instead of the “catch” in the
bpel.
Execute the process. When we look in the console at the instance of the process we see this :

The catch in the bpel itself isn’t getting fired. When we look in the audit trail, we notice the next
message :
It looks like our policy is active. The framework applied the policy. So it first executed the ‘ora-retry’
action (no output on this) and after this it executed the ‘ora-human-intervention’ action. So at this point
we should be able to apply some other actions on the faulted activity (the invoke of the webservice).
From here we have 2 options. The first is the activities-tab. On this tab we will find all activities
executed, and which faulted with the faultname. On the left we select the ‘Pending’ state in the
‘Activity State’ checkbox. On the right we will see the faulted invoke of our webservice. If we select
the checkbox on the left of the activities we can make use of the ‘bulk update’- functionality on more
then 1 instance. We select the invoke activity and in the listbox we can select one of the following
actions :
• Retry
• Abort
• Rethrow
• Replay
• Continue
The second option is the ‘interactions’-tab available in the view when we selected the faulted instance.
In here we will find all the activities from the current process-instance. Select the invoke-activity
(sayHello). In the next screen we will see some sort of Error Hospital. Notice the new State of the
current instance : open.pending.recovery.
We will be able to update all the payload of the variables of the activities in the process, execute
different actions on them, chain the outcomes or just created new instances.
First select the variable in the “Available Variables”-listbox for which we want to update the payload.
Click the get-button. In the textarea we’re now able to insert different payload. After inserting the
correct values, click the set-button and go to the “Actions available”-listbox and select the appropriate
action. The last step is to either choice to recover the current instance, or create a new one.
In our scenario we redeployed the webservice, so the wsdl is reachable again. We updated the sayHello
inputvariable just to see some changes in the updated instance later on. After this we just click the
Recover-button. Select the visual flow, and click on the invoke activity (sayHello).
As we can see in the output. The payload of the inputVariable of the sayHello has been updated and the
framework executed the retry after it. We redeployed the webservice, so it was reachable again, and the
invoke executed correct too.
I hope with the information in this article the functionality of the new fault policy framework is a bit
clear.

Oracle BPEL Fault Policies

Fault Policy Overview


* Since 10.1.3.3
* Catches all faults from an invoke activity (both run time and business faults)
* Overrides all catch activities in BPEL process.
* A fault policy defines conditions and their corresponding fault recovery actions.
* Fault policies are defined in multiple files under directory:
- bpel\domains\default\config\fault-policies
* XSD files are:
- bpel\system\xmllib\fault-policy.xsd
- bpel\system\xmllib\fault-policy-binding.xsd
* A fault policy can be associated at the following levels:
- Partner link
- Port type
- Process level via bpel.xml
- Domain level via fault-bindings.xml
* Fault policy binding order:
-> bpel.xml: partner link -> port type -> process
-> domain: partner link -> port type -> process
-> Catch blocks defined in bpel diagram.
SOA Fault Types
Business Faults
* Programmer defined.
* Defined in WSDL.

Runtime Faults
* Predefined, e.g.
- remoteFault
- bindingFault
* Infrastructure faults, e.g.
- Service down
- Network outage
* Data format errors

Design a Fault Policy


Create a Fault Policy File
* Create policy file (e.g. my-policies.xml) in bpel\domains\domain_name\config\fault-policies
directory

Define conditions
* Conditions are based on faultName. e.g.

<faultName
xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
name="bpelx:remoteFault">

* Multiple conditions are allowed for a single faultName


- if so, conditions are evaluated sequentially

<condition>
<test>$fault.code/code="WSDLReadingError"</test>
<action ref="ora-terminate"/>
</condition>
<condition>
<action ref="ora-java"/>
</condition>

* Each condition has


- one test section which is an XPath expression against fault variable

<test>$fault.code/code="WSDLReadingError"</test>
- one action section which references to the action defined in the same file

<action ref="ora-terminate"/>

- No test condition catches all

<condition>
<action ref="ora-rethrow"/>
</condition>

- No faultName catches all faults

<faultName > . . . </faultName>

Define actions
* See examples below.

Fault Policy Examples


* Conditions

<Conditions>
<!-- when bpelx:remoteFault, retry -->
<faultName
xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
name="bpelx:remoteFault">
<condition>
<action ref="ora-retry"/>
</condition>
</faultName>

<!-- when bpelx:bindingFault, rethrow fault -->


<faultName
xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
name="bpelx:bindingFault">
<condition>
<action ref="ora-rethrow-fault"/>
</condition>
</faultName>
</Conditions>

* Actions

<!-- retry Action -->


<Action id="ora-retry">
<retry>
<retryCount>8</retryCount>
<retryInterval>2</retryInterval>
<retryFailureAction ref="ora-terminate"/>
<exponentialBackoff/>
</retry>
</Action>

<!-- replayScope Action -->


<Action id="ora-replay-scope">
<replayScope/>
</Action>

<!-- rethrowFault Action -->


<Action id="ora-rethrow-fault">
<rethrowFault/>
</Action>

<!-- humanIntervention Action -->


<Action id="ora-human-intervention">
<humanIntervention/>
</Action>

<!-- abort Action -->


<Action id="ora-terminate">
<abort/>
</Action>

<!-- Custom Java Action -->


<Action id="ora-java">
<javaAction className="mypackage.myClass"
defaultAction="ora-terminate"
propertySet="propSet1">
<returnValue value="R_TRM"
ref="ora-terminate"/>
<returnValue value="R_THRW"
ref="ora-rethrow-fault"/>
</javaAction>
</Action>

- Java class must implement IFaultRecoveryJavaClass interface

public interface IFaultRecoveryJavaClass {


public void handleRetrySuccess(IFaultRecoveryContext ctx );
public String handleBPELFault(IFaultRecoveryContext ctx );
}

Associate a Fault Policy


* Process level
- Configured in bpel.xml file.
- Only one fault policy can be bound to a process, port type, or partner link.
- Multiple port types or partner links can be bound to a single fault policy.

<faultPolicyBindings>
<!-- Fault on any plink/port type not specified -->
<!-- below uses policy BillingFaults -->
<process faultPolicy="BillingFaults"/>
<partnerLink xmlns:credit="http://services.otn.com" faultPolicy="CRM_
ServiceFaults">
<!-- Fault on these 2 plink will use policy CRM_ServiceFaults -->
<name>UnitedLoanService</name>
<name>StarLoanService</name>

<!----Fault on these 2 port types uses policy CRM_ServiceFaults -->


<portType>credit:CreditRatingService</portType>
<portType xmlns:united="http://services.uninted.com/loan">
united:UnitedLoanService</portType>
</partnerLink>
<partnerLink faultPolicy="myOtherFaults">
<!-- Fault on this plink uses policy myOtherFaults -->
<name>AnotherPartnerLink</name>
</partnerLink>
</faultPolicyBindings>

* Domain level
- Configured in OracleAS_2\bpel\domains\default\config\fault-bindings.xml file.

<!-- all processes in this domain use DefaultPolicy -->


<process faultPolicy="DefaultPolicy"/>

<partnerLink faultPolicy="DefaultPolicy">
<!-- all invoke faults at partner link creditRatingService use DefaultPolicy
-->
<name>creditRatingService</name>
</partnerLink>

<partnerLink faultPolicy="DefaultPolicy">
<!-- all invoke faults at specific port type use DefaultPolicy -->
<portType
xmlns:db="http://xmlns.oracle.com/pcbpel/adapter/db/insert/">db:insert_plt</p
ortType>
</partnerLink>

Human Intervention in Oracle BPEL Control


* Login BPEL console
* Click Activities tab
* Seach activities based on states
- All States: Displays all activities, regardless of their state.
- Open: Displays only open activities.
- Completed: Displays only completed activities.
- Cancelled: Displays only cancelled activities.
- Stale: Displays only stale activities.
- Pending: Displays only pending activities.
* Click the faulted activity
* Optionally change the variable values
* Select action to take
- Retry: Retries the activity with an option to provide a retry success action.
- Abort: Terminates the process instance of the faulted activity.
- Rethrow: Rethrows the exception and allows the BPEL fault handlers (catch branches) to handle the
fault.
- Replay: Replays the scope in which the fault occurred.
- Continue: Skips the activity. The framework assumes the activity completed with no fault.
* Click the Recover button.

Oracle BPEL Fault Policy Framework handling custom


business faults
Posted in bpel,oracle by Eric Elzinga on February 14, 2009
From the Oracle forum and from the comments on my article about Oracle BPEL Fault Policy
Management i get a lot of questions about how to let the framework handle my own custom defined
‘business faults’.
In certain situations the default set of faults defined by Oracle aren’t suited enough and you need to
define your own faults.
If we look into the examples which got supplied by Oracle we can see an example over here. In this
example they defined their own NegativeCredit-fault.
The Oracle BPEL Fault Policy Framework by default only handles the faults which are getting returned
on an invoke-activity.
So we have our own custom fault and the knowledge we can only let this fault getting catched by the
framework by use of an invoke.
So we need atleast for this testscenario 2 bpel processes. One mainprocess which calls a subprocess,
and this subprocess will throw the custom business fault.
This fault will get propogated back to the mainprocess and in here we will be able to let the framework
handle the fault.
BPEL Processes
Mainprocess

Subprocess
Just a simple invoke of the subprocess from the mainprocess. The subprocess with throw a fault, and
this fault will be catched in the mainprocess.

The fault to be thrown


From the console start the mainprocess and wait till it comes back with a fault message

Click the activity to see the thrown fault


view source
print?
01 [2009/02/13 16:24:41]
02 "{http://nl.iteye/integration/faults/business}BusinessFault" has been thrown.
03
04 <BusinessFault xmlns="http://nl.iteye/integration/faults/business">
05 <part name="payload">
06 <BusinessFault xmlns="http://nl.iteye/integration/faults/business">
07 <FaultCode>999</FaultCode>
08 <FaultMessage>Something went wrong!</FaultMessage>
09 </BusinessFault>
10 </part>
11 </BusinessFault>
Ok nice!
So the custom fault we defined in the subprocess reaches the
mainprocess.
Now we need to config the fault policy framework so it will get
active on our custom business fault.
From the fault we pasted above we need the faultname (BusinessFault)
and the namespace (http://nl.iteye/integration/faults/business).
Edit /bpel/domains/default/config/fault-policies/DefaultPolicy.xml and add the next fault :
view source
print?
<faultName xmlns:flt="http://nl.iteye/integration/faults/business"
1
name="flt:BusinessFault">
2 <condition>
3 <action ref="ora-human-intervention"/>
4 </condition>
5 </faultName>
For testing we will just let this fault getting handled by human-
intervention.
Now restart the components
opmnctl stopall
opmnctl startall
Now start the mainprocess again and wait till it fails.

It looks like the framework got active (activity yellow marked) on our custom
business fault.

Go to the activities-tab

And click the activity which faulted.


Now we can edit some of the values and let the subprocess get re-invoked.
So, at this moment we’re able to throw our custom business faults and let them getting catched by the
framework. Since the fault is only getting catched on the invoke of a partnerlink, we aren’t able to let
our custom business fault getting throwned to the process in which we maybe want do something with
the data for which we actually throwed the custom business fault. So maybe we want to stay in the
subprocess and somehow get the custome business fault thrown inhere, let the framework catch it and
update the values of this subprocess with new values an re-execute the subprocess.
The next solution will get this done.
The mainprocess won’t get changed but in the subprocess we will invoke a new process called
AllBusinessFaults.
New subprocess 2

AllBusinessFaults
The AllBusinessFaults will throw the custom business fault we ‘request’ back on the invoke in this
subprocess. Now it wil get catched by the framework and we will be able to change the values of the
subprocess instead of the mainprocess.

By using the AllBusinessFaults bpel service like a sort of composite service, we can add the custom
business faults in it and throw the one we would like to get thrown. This will work if the collection of
custom business faults isn’t that big. I’m sure there will be better solutions for this, but for the scenario
i wanted to describe inhere it was good enough for me.
Question
In the examples i provided i don’t use the fault-part of a synchronous invoke to propegate the soap-
fault back to the caller, i just throw the fault. The bpel engine itself throws the fault back to the first-
level. Whats best practice on this one ?

Das könnte Ihnen auch gefallen