fault policy doc

24
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 :

Upload: jaysankarmurthir

Post on 07-Apr-2015

447 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Fault Policy Doc

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

Page 2: Fault Policy Doc

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">

05  <!-- Enabling this will cause all processes in this domain to use this

06          fault policy 07     <process faultPolicy="DefaultPolicy"/> 08   -->

09  <!-- DefaultPolicy is defined in ./fault-policies/DefaultPolicy.xml -->

10   <partnerlink faultPolicy="DefaultPolicy">

11    <!-- Enabling this will cause all invoke faults at partner link

12            name of "creditRatingService" to use fault policy with 13            id id = DefaultPolicy 14       <name>creditRatingService 15     -->

16    <!-- all invoke faults at partner link below port type use fault policy

17            with id = DefaultPolicy

18           The following entry covers the samples/tutorials/122.DBAdapter/InsertWithCatch sample. -->

19    <porttype xmlns:db="http://xmlns.oracle.com/pcbpel/adapter/db/insert/">db:insert_plt</porttype>

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"

Page 3: Fault Policy Doc

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">

07  <!-- This section describes fault conditions. Build more conditions with faultName, test and action -->

08   <conditions> 09     <!-- Fault if wsdlRuntimeLocation is not reachable -->

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

11       <condition> 12         <action ref="ora-retry"/> 13       </condition> 14     </faultname> 15     <!-- Fault if location port is not reachable-->

16     <faultname xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:bindingFault">

17       <condition> 18         <action ref="ora-rethrow-fault"/> 19       </condition> 20     </faultname> 21   </conditions> 22   <actions>

23    <!-- This action will attempt 8 retries at increasing 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

Page 4: Fault Policy Doc

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 -->

3   <faultname xmlns:bpelx="http://schemas.oracle.com/bpel/extension" 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 )

Page 5: Fault Policy Doc

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"/>

6        <!-- DefaultPolicy is defined in ./fault-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">

07  <!-- This section describes fault conditions. Build more conditions with faultName, test and action -->

08   <conditions> 09     <!-- Fault if wsdlRuntimeLocation is not reachable -->

Page 6: Fault Policy Doc

10     <faultname xmlns:bpelx="http://schemas.oracle.com/bpel/extension" 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>

20    <!-- This action will attempt 8 retries at increasing 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>

36    <!-- This is an action will mark the work item to be "pending 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

Page 7: Fault Policy Doc

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.

**updateTo 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’

Page 8: Fault Policy Doc

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)

Page 9: Fault Policy Doc

* 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">

Page 10: Fault Policy Doc

 

* 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>

Page 11: Fault Policy Doc

<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>

Page 12: Fault Policy Doc

- 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 -->

Page 13: Fault Policy Doc

<portType xmlns:db="http://xmlns.oracle.com/pcbpel/adapter/db/insert/">db:insert_plt</portType> </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

Page 14: Fault Policy Doc

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

Page 15: Fault Policy Doc

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

Page 16: Fault Policy Doc

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 ?

1 <faultName xmlns:flt="http://nl.iteye/integration/faults/business" name="flt:BusinessFault">

2          <condition> 3                  <action ref="ora-human-intervention"/> 4          </condition> 5 </faultName>

Page 17: Fault Policy Doc

For testing we will just let this fault getting handled by human-intervention.Now restart the components

opmnctl stopallopmnctl 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.

Page 18: Fault Policy Doc

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

Page 19: Fault Policy Doc

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.

QuestionIn 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 ?