Wednesday, 23 November 2011

Basics of the fault management framework in oracle SOA 11g Part B

Hi,
   In part A of my fault management framework tutorial, we came in touch with the basics of the fault management framework in Oracle SOA Suite 11g.In this post, we are going to build on our gained knowledge and see how to use the <javaAction> in our fault policy file.

First, we are going to modify our fault-policy file.To do that, open the "my-fault-policy.xml" file by double clicking on it in the application navigator.Next, replace the entire code with the following code:-


 <?xml version="1.0" encoding="UTF-8"?>
<faultPolicies xmlns="http://schemas.oracle.com/bpel/faultpolicy">
  <faultPolicy version="2.0.1" id="sampleFaultPolicy"
               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:flt="http://xmlns.oracle.com/FaultPolicyTestApp/FaultPolicyTest/FaultThrower" name="flt:MyCustomFault">
        <condition>
          <test>$fault.faultPart/flt:fault_code="custom"</test>
          <action ref="my-abort-action"/>
        </condition>
      
        <condition>
          <test>$fault.faultPart/flt:fault_code="rethrow"</test>
          <action ref="my-rethrow-action"/>
        </condition>
      
        <condition>
          <action ref="my-java-action"/>
        </condition>
      

      
     </faultName>
  
  
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
                 name="bpelx:bindingFault">
        <condition>
          <action ref="my-abort-action"/>
        </condition>
      </faultName>
    
    
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
                 name="bpelx:remoteFault">
        <condition>
          <action ref="my-human-intervention-action"/>
        </condition>
      </faultName>
    
    
    
    </Conditions>
    <Actions>
      <!-- This is an action will mark the work item to be "pending recovery from console"-->
      <Action id="my-retry-action">
        <retry>
          <retryCount>5</retryCount>
          <retryInterval>1</retryInterval>
          <exponentialBackoff/>
          <retryFailureAction ref="my-human-intervention-action"/>
        </retry>
      </Action>
    
      <Action id="my-human-intervention-action">
        <humanIntervention/>
      </Action>
    
      <Action id="my-abort-action">
        <abort/>
      </Action>
    
      <Action id="my-replay-action">
        <replayScope/>
      </Action>
    
      <Action id="my-rethrow-action">
        <rethrowFault/>
      </Action>
    
      <Action id="my-java-action">
        <javaAction className="faultpolicytest.MyFaultHandler" defaultAction="my-abort-action" propertySet="my-prop-set">
 
          <returnValue value="ABORT" ref="my-abort-action"/>
          <returnValue value="RETRY" ref="my-retry-action"/>
        </javaAction>
      </Action>
    

    </Actions>
  
    <Properties>
      <propertySet name="my-prop-set">
        <property name="myProperty">Hello</property>
      </propertySet>
    </Properties>
  
  </faultPolicy>
</faultPolicies>


 We have made a couple of changes in the fault policy file.First, note that we have added a new action in the <Actions> section.This is the java action:-

  <Action id="my-java-action">
        <javaAction className="faultpolicytest.MyFaultHandler" defaultAction="my-abort-action" propertySet="my-prop-set">
 
          <returnValue value="ABORT" ref="my-abort-action"/>
          <returnValue value="RETRY" ref="my-retry-action"/>
        </javaAction>
      </Action>


The <javaAction> tag has the following attributes:-

className is the name of the custom java class.This is mandatory.
defaultAction specifies the action to take.We are coming back to it later.This is mandatory.
propertySet specifies the property set to use.This is optional.

 The custom java class that is going to handle the fault implements the interface:-              oracle.integration.platform.faultpolicy.IFaultRecoveryJavaClass.


The interface has two methods:-

  •  public void handleRetrySuccess(IFaultRecoveryContext context)
  •  public String handleFault(IFaultRecoveryContext context)
The handleRetrySuccess method is called after a successful retry attempt.The handleFault method is invoked when a fault occurs and java action has been specified against that fault.
The BPELFaultRecoveryContextImpl class implements the interface IFaultRecoveryContext and provides more options compared to the IFaultRecoveryContext.

 The handleFault method, after doing it's processing, returns a string value.This returned string value is compared to each of the <returnValue> tag's "value" attribute's value to find a match.If a match is found, the corresponding action is taken.If no match is found, the <defaultAction> is executed.

For logging purpose, a set of properties can be specified in the fault-policy file which can be retrieved from the java class.If you notice, we have defined a property set in the fault policy file after the <Actions> section:-

<Properties>
      <propertySet name="my-prop-set">
        <property name="myProperty">Hello</property>
      </propertySet>
   </Properties>


Again, through the <javaAction> tag's "propertySet" attribute, we have associated this property set to our java action.




Next, open the "FaultPolicyTestApp" in JDeveloper.I am using JDeveloper 11.1.1.5.First we are going to create the java class.To do this, right click on the "FaultPolicyTest" project and select the new option.



In the "New Gallery", select the "All Technologies" tab and in the left pane, select the "Java" node under the "General" category.On the right, select the "Java Class" option.



In the "Create Java Class" window, enter a name for the class.To follow along, enter "MyFaultHandler".Leave the default package name i.e. "faultpolicytest". Uncheck the "Constructors from Superclass" and the "Implement Abstract Methods" check boxes.Use the following image as a  guide:-


In the "Choose Source Folder" window, choose the "SCA-INF\src" option as indicated in the image below.




Next, we are going to add oracle.xml.parser.v2 library in our classpath.To do this, right click on the project and click on "Project Properties".



In the "Project Properties" window, on the left pane, select the "Libraries and Classpath" option.Next, click on the "Add Library" option.




In the "Add Library" window, select the "Oracle XML Parse v2" library and hit OK.



Verify that the library has been added.Hit OK once you are done.




Next, copy and paste the following code inside the Java class.


package faultpolicytest;
import com.collaxa.cube.engine.fp.BPELFaultRecoveryContextImpl;

import java.util.Map;

import oracle.integration.platform.faultpolicy.IFaultRecoveryJavaClass;
import oracle.integration.platform.faultpolicy.IFaultRecoveryContext;
import oracle.xml.parser.v2.XMLElement;

public class MyFaultHandler implements IFaultRecoveryJavaClass{

  public void handleRetrySuccess(IFaultRecoveryContext context){
    System.out.println("handleRetrySuccess invoked");
  }
 
  public String handleFault(IFaultRecoveryContext context){
   
    try{
    BPELFaultRecoveryContextImpl bpelContext=(BPELFaultRecoveryContextImpl)context;
    Map props=bpelContext.getProperties();
    System.out.println(props.get("myProperty"));
    XMLElement element=(XMLElement)bpelContext.getVariableData("inputVariable", "payload","/ns1:process/ns1:input");
    System.out.println(element.getText());
    }catch(Exception e){
      e.printStackTrace();
    }
    return "ABORT";
     
  }
  
}

So we are done.Deploy and test the process.Enter "hello" as input so that the java action is fired.The "FaultPolicyTester" BPEL instance should be terminated.Check the SOA server logs for messages printed to the output.

This ends our journey.The fault management framework is very powerful and if used in correct scenarios, it can get rid of code repetition.In these posts, we have barely scratched the surface of the fault management framework.I hope after going through these posts, you will have the basic understanding of how fault management framework works.

Hope this helps.Any comment or suggestion is much appreciated.

       

                   


Basics of the fault management framework in oracle SOA 11g Part A

Hi,

   In this post, I am going to discuss the basics of fault management framework in Oracle SOA suite 11g.Before proceeding, you should have the basic understanding of faults and how they are handled in Oracle SOA 11g.For this, you can refer to my post :

http://rahullahiri.blogspot.com/2011/02/basic-fault-handling-in-soa-11g.html


Fault management framework is a unified framework for handling faults in Oracle SOA Suite 11g.It uses XML based policy files that specify what action to take based on the type of fault.Let us get started straight away and we shall see how it is done.

First, open JDeveloper if it is not already open.Next, go to file and click on new.




On the left pane, select the application node and from the items, select SOA application.Hit OK once you are done.



In the create SOA application window, enter a name for the application.To follow along,enter the name "FaultPolicyTestApp".Hit next once you are done.



In the next screen, enter a name for the project.To follow along, enter the name "FaultPolicyTest".Hit next once you are done.



In the next screen, choose the empty composite option and hit finish.

Next,drag and drop a BPEL process onto the empty composite.In the create new BPEL window, enter a name of your choice.To follow along, enter "FaultThrower".Choose the synchronous template action.Leave the other defaults.Use the following image as a guide:-







For the sake of demonstration,we are going to see how to handle system faults as well as custom faults through fault policies.

Open the "FaultThrower.xsd" by expanding the xsd node in the application navigator and double clicking on the file.Next, go to source and copy and paste the following code snippet at the position as indicated in the image below:-


<element name="fault">
    <complexType>
      <sequence>
        <element name="fault_code" type="string"/>
        <element name="fault_message" type="string"/>
      </sequence>
    </complexType>
  </element>






Click on save all to save the changes.Close the XSD file as we are done with it.

Next, we are going to create a fault message based on this type and modify the operation for the BPEL process to return a fault.To do this, open the  FaultThrower.wsdl file by double clicking on it in the application navigator.Then go to the source.


Next, enter the following code snippet just below the messages section.Use the following image as a guide.

<wsdl:message name="MyFaultMessage">
    <wsdl:part name="faultPart" element="client:fault"/>
  </wsdl:message>







Next, inside the operation under the portType, add the following line of code after the the output.Use the following image as a guide:-



<wsdl:fault message="client:MyFaultMessage" name="MyCustomFault"/>


Save the changes by clicking on save all and close the WSDL document as we are through with it.

 Next, open the FaultThrower BPEL process.Now, create a new variable that we are going to use as a fault variable.To do this, click on the create variable icon in the main BPEL process scope as indicated in the image below:-



 In the variables window, click on the green plus sign to add a new variable.






The create variable window will pop up.Enter a name of your choice.To follow along, enter "myFaultVariable".Choose the "Message Type " radio button and click on the magnifying glass beside it to choose the message.






In the type chooser, select the fault message that we created previously in the "FaultThrower.wsdl".



Hit OK three times to dismiss all the windows.Next, drag and drop a Throw activity onto the BPEL process from the component palette between the receive and reply activity.



Next double click on the throw activity to modify it.Enter a name of your choice.To follow along, enter "Throw_customfault".Next, click on the magnifying glass under the Fault QName section as indicated in the
image below:-



The fault chooser window will pop up.Expand the "Project WSDL Files" node and select the "MyCustomFault" node under the "FaultThrower.wsdl" node.



Next, click on the magnifying glass beside the Fault Variable.






In the variable chooser window,select the myFaultVariable node and hit OK.






Hit OK again to dismiss the Throw activity configuration window.Click on save all to save the changes.

Next, drag and drop an assign activity just before the "Throw_customfault" activity.




Rename the assign activity to Assign_fault.Then double click on the assign activity.The Edit Assign window will pop up.Create two copy operations:-


              From inputVariable's input element to the myFaultVariable's fault_code element

              From inputVariable's input element to the myFaultVariable's fault_message element

Use the following image as a guide.




Hit OK once you are done.The BPEL process should look like the following image.




Next, we are going to create our fault management framework configuration files.As mentioned earlier, the fault management framework uses XML based policy files to catch faults.There are two files that are used for this purpose:-
                                         

  •   The fault policy file
  •   The fault binding file 

         Through the fault policy file, we can specify what action to take based on the type of the fault.By default,the name of the policy file has to be "fault-policies.xml".The fault binding file is used to bind the fault policy to the composite or a particular SCA component.By default, the name has to be "fault-bindings.xml".(Of course we can use custom names for fault policy and fault binding files which we are going to see in a moment).

So, let us create a fault policy file first.For this, right click on your project and select new.




In the new gallery, select the "All technologies tab".On the categories pane, select the "XML" node under "General" and on the right, select the "XML document" option.Hit OK once you are done.


In the "Create XML File" window,enter the name "my-fault-policy.xml".As you see, we are using custom name for our fault policy file.If we use a custom name for our fault-policy and fault binding files, then we will have to configure some properties in the composite.xml.Had we used the default name i.e. fault-policies.xml then we would have saved ourselves this trouble.

Next, copy and paste the following code inside the fault policy file.



<?xml version="1.0" encoding="UTF-8"?>
<faultPolicies xmlns="http://schemas.oracle.com/bpel/faultpolicy">
  <faultPolicy version="2.0.1" id="sampleFaultPolicy"
               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:flt="http://xmlns.oracle.com/FaultPolicyTestApp/FaultPolicyTest/FaultThrower" name="flt:MyCustomFault">
        <condition>
          <test>$fault.faultPart/flt:fault_code="custom"</test>
          <action ref="my-abort-action"/>
        </condition>
       
        <condition>
          <test>$fault.faultPart/flt:fault_code="rethrow"</test>
          <action ref="my-rethrow-action"/>
        </condition>
       
        <condition>
          <action ref="my-human-intervention-action"/>
        </condition>
       
     </faultName>
   
   
   
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
                 name="bpelx:bindingFault">
        <condition>
          <action ref="my-abort-action"/>
        </condition>
      </faultName>
     
     
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
                 name="bpelx:remoteFault">
        <condition>
          <action ref="my-human-intervention-action"/>
        </condition>
      </faultName>
     
     
     
    </Conditions>
    <Actions>
          <Action id="my-retry-action">
        <retry>
          <retryCount>5</retryCount>
          <retryInterval>1</retryInterval>
          <exponentialBackoff/>
          <retryFailureAction ref="my-human-intervention-action"/>
        </retry>
      </Action>
     
      <Action id="my-human-intervention-action">
        <humanIntervention/>
      </Action>
     
      <Action id="my-abort-action">
        <abort/>
      </Action>
     
      <Action id="my-replay-action">
        <replayScope/>
      </Action>
     
      <Action id="my-rethrow-action">
        <rethrowFault/>
      </Action>
     
    </Actions>
  </faultPolicy>
</faultPolicies>


Let us take the code chunk by chunk.Every fault policy file has as the element <faultPolicies> element as it's root element.Under the faultPolcies element, there can be multiple <faultPolicy> nodes.So the basic structure looks like:-


              <faultPolicies.........>


                    <faultPolicy  id="PolicyA" .....................................>
                    </faultPolicy>

                    <faultPolicy  id="PolicyB" .....................................>
                    </faultPolicy>
                      ...
                      ...
                      ...
                       
               </faultPolicies>


In our fault policy, we have declared only one faultPolicy having the id "sampleFaultPolicy".Under each <faultPolicy>, we can declare a set of conditions signified by the <Conditions> tag and a set of actions signified by the <Actions> tag.

<faultPolicies ...........>
   <faultPolicy ..................>

               <Conditions>
                     ...
                     ...
                     ...

                </Conditions>


              <Actions>
              
                  ...
                  ...
                  ...
 
              </Actions>


   </faultPolicy>
     
      ...
      ...
      ...
</faultPolicies>



Let us take the <Actions> tag first.Under this, we specify the action(s) that are to be taken.Inside the <Actions> tag, we can have single or multiple <Action> tags.So the basic structure looks like:-



      
<faultPolicies ...........>
   <faultPolicy ..................>

               <Conditions>
                     ...
                     ...
                     ...

                </Conditions>


              <Actions>
              

                          <Action id="<%action_id%>">
                               ...
                          </Action>
                     
                           <Action id="<%action_id%>">
                               ...

                          </Action>
                   
                           ...
                           ...
 
              </Actions>


   </faultPolicy>
     
      ...
      ...
      ...
</faultPolicies>


  The action id attribute is at your discretion.You can name it as you wish (with some standard naming restrictions e.g. action ID's can not begin with a numeric character and so on).Inside <Action> however, you can only specify the following actions:-

  •        <abort/>  :-                   To terminate the process flow
  •        <retry/>   :-                   To retry the process instance again
  •        <rethrowFault/> :-         To simply throw the fault.
  •        <replayScope/> :-         To re-execute the scope in which the fault has taken place
  •        <humanIntervention/> :- To recover the process manually
  •        <javaAction/>:-              To specify a custom java class for handling the fault.(explained later)

So let us examine the <Actions> section of our fault policy:-

<Actions>

          <Action id="my-retry-action">
                <retry>
                    <retryCount>5</retryCount>
                   <retryInterval>1</retryInterval>
                  <exponentialBackoff/>
                  <retryFailureAction ref="my-human-intervention-action"/>
               </retry>
      </Action>
     
      <Action id="my-human-intervention-action">
        <humanIntervention/>
      </Action>
     
      <Action id="my-abort-action">
        <abort/>
      </Action>
     
      <Action id="my-replay-action">
        <replayScope/>
      </Action>
     
      <Action id="my-rethrow-action">
        <rethrowFault/>
      </Action>
     
    </Actions>

                            

We have specified all the actions that we can perform except the java action which we are going to see a bit later.Pay attention to the retry action.Inside retry, we have specified four elements:-

   <retryCount> specifies number of retry attempts.This is a mandatory element.

   <retryInterval> specifies the interval between the retry attempts in seconds.Also mandatory.

   <exponentialBackoff> is an optional element.When specified, the retry interval is doubled from the previous retry interval each time.

    <retryFailureAction> is an optional element with a single attribute "ref".It specifies the action to take when all retry attempts has failed.


Let us now examine the <Conditions> element.Under the <Conditions> section we can have single or multiple <faultName> elements.These elements specify which fault to handle.So,the basic structure looks like this:-

<faultPolicies ...........>
   <faultPolicy ..................>

               <Conditions>

                    <faultName name="<%qualified fault name%>">
                        ...
                        ...
                        ...
                    </faultName>


                  
                    <faultName name="<%qualified fault name%>">
                        ...
                        ...
                        ...

                    </faultName>
                     ...
                     ...
                     ...

                </Conditions>


              <Actions>
              
                  ...
                  ...
                  ...
 
              </Actions>


   </faultPolicy>
     
      ...
      ...
      ...
</faultPolicies>

The name attribute of the <faultName> tag is an optional attribute. If it is not specified, it means we intend to catch any fault that occurs.It is synonymous with the catchAll BPEL activity or the "catch(Exception e){}" java code fragment.If you want to catch a specific fault, then the namespace qualified fault name has to be specified.Let us look at one of our faultName segments in our fault policy :-

<faultName xmlns:flt="http://xmlns.oracle.com/FaultPolicyTestApp/FaultPolicyTest/FaultThrower" name="flt:MyCustomFault">

       ...
       ...
       ...


</faultName>


Here we have specified the qualified fault name of the custom fault that we create in our WSDL file.Examine the value of the name attribute.It is the namespace qualified name of our custom fault.

Inside the faultName element, we can have single or multiple <condition> elements.As it's name suggests, it used for checking conditions.So, the basic structure looks like:-



<faultPolicies ...........>
   <faultPolicy ..................>

               <Conditions>

                    <faultName name="<%qualified fault name%>">
                       
                        <condition>
                           ...
                           ...
                           ...
                        </condition>

                        <condition>
                           ...
                           ...
                           ...

                        </condition>


                    </faultName>


                  

                    <faultName name="<%qualified fault name%>">
                        ...
                        ...
                        ...

                    </faultName>
                     ...
                     ...
                     ...

                </Conditions>


              <Actions>
              
                  ...
                  ...
                  ...
 
              </Actions>


   </faultPolicy>
     
      ...
      ...
      ...
</faultPolicies>




Let us now look at a condition element from our fault policy file:-

      <condition>
          <test>$fault.faultPart/fault_code="custom"</test>
          <action ref="my-abort-action"/>
        </condition>


 The <test> element inside the condition is an optional element that checks for a condition.If it is not present, then it is synonymous with the "else" construct i.e. it is executed for all conditions.Now look closely at the expression inside the test.On the left hand side of the "=" operator, we have specified the expression:-

                                                $fault.faultPart/flt:fault_code

Here we are extracting the value of the fault_code element from our custom fault variable "myFaultVariable".The expression above follows the following format:-

                               $fault.<%part_name%>/<Location>

Here <%part_name%> is the part name that we specified in our WSDL document while creating the fault message:-


  <wsdl:message name="MyFaultMessage">
    <wsdl:part name="faultPart" element="client:fault"/>
  </wsdl:message>


The expression $fault.<%part_name%> returns you the root element (in our case this is the <fault> element) from where you can specify the XPath of your node which you want to extract the value from.

The <action> element specifies the action to perform.The "ref" attribute of the <action> tag refers to the "id"  attributes of the <Action> element.

Let us look at the <Conditions> section of our fault policy then.

                             
<Conditions>
   
     <faultName xmlns:flt="http://xmlns.oracle.com/FaultPolicyTestApp/FaultPolicyTest/FaultThrower" name="flt:MyCustomFault">
        <condition>
          <test>$fault.faultPart/fault_code="custom"</test>
          <action ref="my-abort-action"/>
        </condition>
       
        <condition>
          <test>$fault.faultPart/fault_code="rethrow"</test>
          <action ref="my-rethrow-action"/>
        </condition>
       
        <condition>
          <action ref="my-human-intervention-action"/>
        </condition>
       
     </faultName>
   
   
   
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
                 name="bpelx:bindingFault">
        <condition>
          <action ref="my-abort-action"/>
        </condition>
      </faultName>
     
     
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
                 name="bpelx:remoteFault">
        <condition>
          <action ref="my-human-intervention-action"/>
        </condition>
      </faultName>
     
    </Conditions>



Look closely at the first <faultName> section.We have declared three <condition> elements inside it.So it works in a similar way like the if..else statements.

Next, let us turn our attentions to the fault-binding file.Create another XML document by right clicking on your project and selecting new->XML->XML document.This time, name the document "my-fault-binding.xml".Next, copy and paste the following code inside the document:-


<?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="sampleFaultPolicy"/>

<!--    
              <component faultPolicy=" <%fault policy name%>" >
                     <name>componentA</name>
                     <name>componentB</name>
                      ...
                      ...
                      ...
               </component>


               <reference faultPolicy=" <%fault policy name%>" >
                            <name>referenceA</name>
                             <name>referenceB</name>
                             <portType></portType>
                             <portType></portType>
                              ...
                              ...
                              ...
               </reference>
                     
               </reference>
-->

</faultPolicyBindings>

 
The fault policy bindings file binds the fault policy to the composite or to specific components or references.In the above example, we are applying our fault policy to the entire composite. i.e. all of the elements in our composite should follow this fault policy should any fault takes place.

Next we must specify two properties in the composite as we are using custom names for our fault policy and fault binding file.To do this, open the composite file and go to the source by clicking on the source tab as indicated in the image below:-





In the source, copy and paste the following code after the component definitions and before the service definitions begin:-

  <property name="oracle.composite.faultPolicyFile">my-fault-policy.xml</property>
  <property name="oracle.composite.faultBindingFile">my-fault-binding.xml</property>





          Save the changes by clicking on save all.So, we are done with our project.(well almost done to be precise).Let us deploy and check whether the fault policy is working or not.

First deploy the project and go to the enterprise manager console and test the service.Enter the string "custom" as the input element.If you take a look at our fault policy file's condition section, you will notice that we have specified to terminate the process flow if the fault code is "custom".In the BPEL process, we copied the input to the fault code element.So, "theoretically" the FaultThrower process should be terminated.But was it the case?Look at the process instances in the EM console.


To our utter surprise, the process flow was not terminated.The fault was not caught.What could have possibly gone wrong?!

And here comes the cause.The fault management framework kicks in only when a fault is thrown while trying to invoke an operation through the invoke activity.In our scenario, this is not the case.We are simply throwing the fault using a throw activity.

Now, let us modify our composite so that we are able to test our fault policy.Open the composite file and delete the faultthrower_client service in the exposed services swim lane i.e. the left most swim lane by right clicking on it selecting delete.


In the confirm delete window, click on "Yes".Next, drag and drop a BPEL process from the component palette onto your composite.Specify a name of your choice.To follow along, enter the name FaultPolicyTester.Select the "one-way BPEL process" option as the template.Next, click on the magnifying glass beside the input as indicated in the image below:-



In the type chooser window, choose the "process" element under the "FaultThrower.xsd" node under "Project Schema Files".Hit OK once you are done.



Verify the settingsHit Ok another time to dismiss the "Create BPEL Process" window.


Next,go back to the composite and wire the FaultPolicyTester BPEL process to the FaultThrower process
.

Next, open the FaultPolicyTester BPEL process by double clicking on it.Next, after the receive activity drag and drop an assign activity followed by an invoke activity onto the BPEL process from the component palette.The BPEL process should look like the following image.


Next, double click on the "Invoke" activity to configure it.In the window that pops up, enter a name of your choice.To follow along, enter "Invoke_faultthrower".Next click on the magnifying glass beside the partnerlink to choose the partner link.

In the partner link chooser, select the FaultThrower.faultthrower_client partner link and hit OK.


Next, generate the Input variable by clicking on the green plus sign beside the Input text box.



In the "Create Variable" window, accept the defaults and click OK.

Next, generate the output variable by clicking on the green plus icon beside the output text box.


In the "Create Variable" window, accept the defaults and click on OK.Verify the settings for the Invoke activity and hit OK to dismiss the window.



Next, rename the assign activity to "Assign_input" and double click on it.Create a copy operations :-

          From inputVariable's input to the Invoke_faultthrower_process_InputVariable's input
         
Use the following image as a guide.Hit OK once you are done.


Save the changes that we made.We are done.

In this scenario, when the FaultThrower process is invoked from the FaultPolicyTester through the Invoke_faultthrower invoke activity, the fault management framework will kick in and execute the policy.So, if we give the input as "custom", the fault management framework will terminate the FaultPolicyTester process flow.

Deploy and test the process now.Give the string "custom" as the input.You will see the process FaultPolicyTester has been terminated.





There is also one thing that you should keep in mind while working with the fault management framework.Always remember that the fault management framework always kicks in before the catch/catchAll  can catch the fault.Whenever a fault occurs while invoking a service, a corresponding fault policy is searched for.If it is found, then actions are taken according to the policy and the process continues.In case a policy is not found, the fault is returned to the BPEL process and this is when catch/catchAll (if any) kicks in.

No comments:

Post a Comment