Saturday, 26 November 2011

what is difference between Abstract wsdl & concrete wsdl ?

what is difference between Abstract wsdl & concrete wsdl ?

Abstract wsdl:-Used on server side,contains request,response and type of operation performed.
concrete wsdl:-used on client side,contains abstract wsdl and transport used.

Abstract WSDL contains only messages and operations. Abstract WSDL is used by web Server where as concrete WSDL contains messages, operations and binding/transport specific information i.e. SOAP over Http/HTTPS/JMS having wsdl style i.e. RPC/DOC literal.

Abstract WSDL consists of the structure of the message that is like what operation, what is the input and what is the ouput . Whereas in concrete WSDL has all the things that the abstract wsdl has in addition it has transport(http,jms) details.


Abstract wsdl:- Used on server side,contains request,response and type of operation performed.
concrete wsdl:- Used on client side,contains abstract wsdl and transport used.

● An abstract WSDL document describes what the web service does, but not how it does it or how to contact it. An abstract WSDL document defines:
the operations provided by the web service.
the input, output and fault messages used by each operation to communicate with the web service, and their format.
● A concrete WSDL document adds the information about how the web service communicates and where you can reach it. A concrete WSDL document contains the abstract WSDL definitions, and also defines:
the communication protocols and data encodings used by the web service.
the port address that must be used to contact the web service.
.
Including Abstract WSDL is reusable because there is no binding details in it whereas Concrete WSDL used for specific service for which it is defined.


Abstract wsdl creation:-
Drag wsdl palette from palette window to designer windoow and make configure the respective input and output schemas and create the porttype  and inside that one create the operation and configure u created the schemas inside of that operation.create one process and Drag soap event source activity and configure ur wsdl just now u created above and make the necessary transport ie http or jms and in the configuration section of ur soap event soap select wsdl source option and select and save that in ur local drive .That is nothing but ur concrete wsdl .Create one folder inside of ur projects and import ur concrete wsdl inside of that directory .create one more soap request reply activity  inside of ur newly created process and configure ur newly imported schema.


Abstract WSDL consists of the structure of the message that is; what operation, what is the input and what is the ouput . Whereas in concrete WSDL has all the things that the abstract wsdl has in addition it has transport(http,jms) details.

Thursday, 24 November 2011

Basic Fault Handling in SOA 11g

n this post, I am going to illustrate the basics of fault handling in Oracle SOA 11g.For the sake of illustration, I am going to create a a sample application.So , let's get started.

In Oracle SOA 11g, faults can be categorized broadly into two categories:- System Faults and Custom Faults.So, let us get started to see how it works.In this first example, we are going to see how faults are propagated.

First,open JDev and create a new SOA Application and a SOA project, select empty composite template.Now drag and drop a  BPEL process onto your composite application.Name it FaultHandlerBPEL and choose synchronous template;leave the default input and output and make sure the "Expose as SOAP service" check box is checked.



 Hit ok once you are done.In the FaultHandlerBPEL process, we are going to handle the faults.Drag another BPEL process.Name it FaultThrowerBPEL.Like before, choose synchronous template and accept the default input and output.However, do not expose this BPEL process .i.e. the check box "Expose as SOAP service" should be unchecked.


As the name implies, the FaultThrowerBPEL process throws a fault Now wire the FaultHandlerBPEL to the FaultThrowerBPEL process.Your composite should look like the following image:-



Now, double click on the FaultThrowerBPEL process to open the BPEL process editor.Now,drag a Throw activity between the receive and reply activity.Name the activity ThrowFault.






Now double click on the Throw activity.A window will pop up.Click on the magnifying glass as shown in the image below to select the fault.



In the fault chooser window, expand the System Faults node and select remoteFault.Hit ok once you are done.



This will bring you back to the previous window.Now click on the green plus sign to add a fault variable as shown in the image below:-


Accept the default name and scope in the variable creation window.Hit Ok twice to come back to the BPEL process.


So in the previous steps, what we have done is we have created a throw activity which throws a remoteFault.While throwing the fault, we have also specified a fault variable.Using the throw activity, we can throw system faults and custom faults.However, the custom faults are discussed later.So, if you are familiar with java, up to now we have written something like this:-

     throw new Exception();

Notice that, once we create a fault variable, a new WSDL file is added to our project.The name of the WSDL file is RuntimeFault.wsdl.The wsdl file is a simple one which contains a message on which the fault variable is based on.It is important to mention here that in SOA 11g, the fault variables must be WSDL message based,be that a custom fault variable or a system fault variable.

Now, drag and drop an Assign activity just before the Throw activity.Name it AssignFaultDetails.The BPEL file should look like the following image:-


Now double click on the assign activity.Add a copy operation.



Choose expression on the from side and enter the string '007'.On the to side,expand the FaultVar node and select the code  part.


Hit Ok once you are done.Now,add another copy operation.On the from side, select expression and enter the string 'My Fault Summary'.On the to side, expand the FaultVar node and select the summary part
.

Add another copy operation.Like before, on the from side select expression and enter the string 'My Fault Details'.On the two side, expand the FaultVar node and select detail node.Hit Ok twice to complete the Assign activity.

So the assign activity populates the fault variable with some dummy data before the fault is thrown. This completes our FaultThrowerBPEL process.

Next open the composite.xml and double click on the FaultHandlerBPEL to open the BPEL editor.Next, drag and drop an Invoke activity onto the BPEL process between the Receive and Reply activity.Double click on the invoke activity.Enter the name InvokeFaultThrower.Next click on the magnifying glass beside the Partner  Link as indicated in the following image:-





The partner link chooser dialog opens.Select the FaultThrowerBPEL.faultthrowerbpel_client partner link and hit ok.




Back in the invoke dialog, create input and output variables.Choose the default name.Your BPEL process should look like the following image.


Add an Assign activity before the invoke activity.Name it initialize variable.Create a copy operation as shown in the follwing image:-
Hit Ok twice to come back to the BPEL process.Add another activity after the Invoke activity and before the Reply activity.Call it IntializeOutput.Create a new copy operation as shown in the following image:-


Hit Ok twice to come back to the BPEL process.Now click on the validate icon on the upper left corner of the BPEL process as shown on the image below:-


All the warning signs from the BPEL process should disappear now.If you test the process now and invoke the FaultHandlerBPEL, when executing the invoke activity InvokeFaultThrower, a fault is going to be thrown.This is because the FaultThrowerBPEL is going to be invoked which is going to throw a remoteFault.As we do not have any catch or catchAll activity in the FaultThrowerBPEL, the fault is going to be propagated to the FaultHandlerBPEL.

Now add a catch all branch.To do this, click on the add catch all branch icon as indicated in the image below:-




A new catch all branch is going to be added to the BPEL process.Expand the catch all activity and drag and drop an Assign activity under the catchAll activity and name it PopulateOutput.The BPEL process should now look like the following image:-





Double click to open the Assign activity and add a copy operation.On the from side select, expression,open the expression builder and enter expression:-

concat(ora:getFaultName(),'::',ora:getFaultAsString())

On the to side, select the result element as shown in the image below:-



The function ora:getFaultName() returns the fault name i.e. remoteFault in this case.The function ora:getFaultAsString() returns the details of the fault which contains all the parts i.e. code, summary and detail.Next drag and drop a Reply activity under the catchAll branch just below the PopulateOutput Asign activity.Your BPEL process should look like the following image:-





Double click to open the Reply activity.Enter replyOutput as the name.Now select the partner link as before.In the partner link chooser, select the faulthandlerbpel_client partner link.Hit ok to comeback to the previous window.


Now click on the magnifying glass beside the Variable chooser as shown in the image below:-








In the variable chooser, choose the output variable.


Hit Ok twice to complete the Reply activity.In the previous steps, we created a catch all branch synonymous to java "catch(Exception e){}".Now,inside the catch all, we have implemented an Assign activity which update the output variable with the details of the fault and a Reply activity which replies to the calling process.

Now deploy and test the service from the EM console.A fault is going to be returned when you invoke the ErrorHandlerBPEL from the EM console.


Returning a fault from a synchronous BPEL process:-

Now we are going to see how we can return a fault from a synchronous BPEL process.To do this, open the FaultThrower BPEL process. Next add a catch branch by clicking on the add catch branch as indicated in the image below:-


Now double click on the catch branch that is created .Now we are going to choose the fault that we intend to catch which is, in this case, a remoteFault.Click on the magnifying glass icon as indicated in the image below to bring up the fault chooser window.



In the fault chooser window, select remoteFault.Hit Ok once you are done.



 Next click on the magnifying glass icon as indicated in the image below to select a fault variable.Here, we are going to reuse the same variable that we created while throwing the fault.Alternatively, you can create a new fault variable by clicking on the green plus icon.In this case, the fault variable is going to be automatically populated when the fault is caught.
.


Next, choose the FaultVar and hit Ok once you are done.Hit Ok again to complete the catch activity.So in java syntax, we have written something like this:-
                       catch(RemoteFault faultVar){}


Now drag and drop a Reply activity under the catch activity.Your BPEL process is going to look like the following image.



Next we are going to configure the reply activity to reply with a fault.Double click on the Reply activity.Enter ReplyFault as name.Choose the faultthrowerbpel_client partner link.Now, select the fault variable as the variable.Next click on the magnifying glass as indicated in the following image  to choose the fault that we intend to return.

In the fault chooser dialog, select remoteFault.Hit Ok once you are done.



The reply activity should look like as shown in the following image.


 Hit Ok to complete the reply activity.The BPEL process should look like the following image.


 Next,we have to configure the operation for the FaultThrower BPEL to indicate that he process can return a fault.To do this, open the FaultThrower.wsdl file and go to source.Notice that the RuntimeFault.wsdl is imported into this WSDL automatically.



Now, add a new fault inside the operation.The fault should be based on the message as defined in the RuntimeFault.wsdl.file.Make sure the namespace is declared.


This completes the BPEL process.Now deploy and test the web service.The behavior is going to be the same;this time though, the fault is caught by the FaultThrowerBPEL.Once caught, the FaultThrowerBPEL replies to the calling BPEL i,e, the FaultHandlerBPEL in this case with a remoteFault.This remoteFault is then caught by the catchAll activity inside the FaultHandlerBPEL.So in java syntax, we are doing something like this in the FaultThrowerBPEL:-


                                ....
                                catch(RemoteFault faultVar){
                                                throw new RemoteFault(faultVar);
                                }

In my next post, I am going to show another powerful fault handling mechanism which is the fault handling framework.Hope this helps.

Difference between rebuild and make in jdeveloper

The difference is ...

  • Rebuild is compiling all selected .java files, regardless if an up-to-date .class file is available or not
  • Make is compiling those selected .java files for which no up-to-date .class file is available PLUS all .java files which are on the source path AND dependent on the selected .java files

Please note that in both cases the selection makes a difference:
  1. if your selection includes only .java files or packages, only files in the same project will be compiled
  2. if you select one or more projects, compilation will also include any projects which depend on the selected project(s). To prevent building a long list of dependend projects the latest builds of JDev offer the feature Build | Make Only and Build | Rebuild Only, respectively.

SOA 10g to 11g Migration Best Practices

Oracle SOA Suite 11g was released couple of years ago and companies are using it to develop integration solutions since then. Those who have developed their integration solutions using SOA Suite 10g they have upgraded their infrastructure and code base to SOA Suite 11g or they are planning to upgrade it to 11g.
SOA Suite 11g has significant differences from SOA Suite 10g. In this post I am writing about the best practices for upgrading SOA 10g code base to SOA Suite 11g.
Pre Migration Best Practices
Ensure that 10g Projects are Up and Running on Latest SOA 10g Release
Before migrating a 10g project its better to verify that the project is up and running. If your project have dependencies on the external web services than make sure that all the external web service are up and running.
Install JDeveloper 11g:
Download latest JDeveloper 11g release and upgrade it with SOA composite editor extension.
Install latest SOA 11g Version:
Download and install latest SOA Suite 11g release (Latest SOA Suite 11g version now is 11.1.1.5 also named as SOA 11g PS4).
Start with One Business Case:
Don’t try to upgrade the complete 10g code base. Select one business case and start upgrading projects needed for the selected business case.
Configure Resources:
Configure all the resources you need to run your application on newly installed SOA 11g server (JMS Queues/Topics, DB Connection pools, Security Policies, Work Managers etc).
Use Scripts to Migrate 10g Projects:
If you are migrating just one project than using JDeveloper migration wizard is a clever choice. If you want to migrate all of your 10g projects into 11g format than using ant-sca-upgrade.xml is a better option. You can write a shell/ant script to upgrade all 10g projects leveraging ant-sca-upgrade.xml. In the next article I will provide an ant script to migrate 10g projects to 11g.
Post Migration Best Practices
Compile Migrated Projects and Fix Compilation Errors.
11g BPEL compiler is stricter than 10g. You might get compilation error for XPath functions or for XPath expressions. Check the compilation logs for errors and fix them. In 11g they changed namespace prefixes for some of the XPath functions, you need to correct the XPath function signature. For example ora:parsexml() is oraext:parsexml now. You can have a look on the 11g XPath functions definitions in <JDEVELOPER_HOME>/integration/seed/soa/configuration folder. This folder contains XPath function definitions for bpel, mediator, mapper etc.
Rearrange Artifacts Into Corresponding Folders.
For a BPEL project, JDeveloper 10g keeps all the artifacts inside bpel folder. JDeveloper 11g organizes artifacts in folders. For example it keeps .xsd files in xsd folder, .wsdl files in wsdl folder and so on. When you upgrade a 10g project to 11g project neither JDeveloper Migration Wizard nor ant-sca-upgrade.xml reorganizes the project artifacts in their corresponding folders. Copy artifacts into corresponding foder. It doesn’t make any difference in the functionality but it will make your 11g projects much cleaner and organized. Don’t forget to modify the path of xsd's, xslt's, wsdl's in the files referring these artifacts.
Create JDeveloper Applications and Projects
When you upgrade a 10g project using ant-sca-upgrade.xml script it won’t generate .jws and .jpr files in the upgraded projects. You need to create applications and projects in JDeveloper manually.
Run 11g Adapter Configuration Wizard to Verify the Adapters
Run 11g adapter configuration wizard for each adapter in an upgraded project to make sure that all the adapter configurations are correct and contains all the required properties. It will also validate the adapter connections to SOA 11g environment.
Update JCA adapter Header Variables
SOA 11g manages JCA adapter header variables in a different manner. JCA adapter header variables are invoke activity properties now. If you are using adapter header variables in SOA 10g projects you need to manually set these adapter header properties on the Properties tab of the Invoke activity dialog box. You can see all the available adapter header properties on the properties tab of the invoke activity. Recompile the modified project to ensure that everything is fine.
Create Configuration Plans for Deployment.
JDeveloper 11g migration wizard or 11g migration script doesn’t upgrade any SOA 10g deployment plan and build scripts. You need to manually create configuration plans for SOA 11g projects. Configuration plans help you to customize environment specific values (i.e. hostname, port, resource locations etc). Click here to find out how to generate and use deployment plans.
Manage Common Artifacts Using MDS
In Fusion Middleware 11g oracle introduces a new way of managing application meta data using MDS (Meta Data Service). MDS is a single unified repository to store all the shared artifacts. MDS provides a unified URL to access an artifact across all the environments. No local copies and no string replacements are required. For example, to access CommonObjects.xsd you need to use the following URL across all the environments:
oramds:/apps/common/xsd/CommonObjects.xsd
If you are accessing any file from bpel xmllib you need to change the URL to MDS URL. For example if you were accessing RuntimeFault.wsdl in 10g BPEL project using URL - http://localhost:80/orabpel/xmllib/RuntimeFault.wsdl you need to change it manually in your code to oramds:/soa/shared/bpel/RuntimeFault.wsdl.
Do the following to leverage MDS repository to efficiently manage your shared resources:
  • Remove local copies of shared artifacts (XSD, WSDL, DVM, XSLT etc)
  • Copy Common artifacts to local JDeveloper MDS repository. Local MDS repository location is <JDEVELOPER_HOME>/integration/seed
  • Change common artifacts URL to MDS URL in the files referring them.
  • Deploy shared artifacts to MDS repository on SOA 11g Server. Click here to learn to deploy and remove artifacts on MDS repository using ant.
Group Upgraded Projects in a Single Composite Application
When you upgrade SOA 10g projects to SOA 11g you will have one SOA composite per upgraded project. In other words you will have as many SCA Composites as many project you have. An SCA composite is used to assemble SCA components in logical groupings. You can not leverage SCA benefits by having many fine grained composites.
Grouping SCA components into an SCA composite is heavily depends on the business case and requirements you have but you can use the following as reference points:
  • Evaluate the functionality provided by the SCA components and then group the related SCA components in a single SCA composite.
  • Assemble a reusable component alone in an SCA composite. Expose the component as a service using service bindings so other SCA components/composites can reuse it.
  • Consider message size and complexity of the component implementation as well while assembling SCA Composite.
Create Partitions to Group Composites
In SOA 10g you have BPEL domains to logically organize BPEL processes and ESB System and Service Group for organizing ESB flows. In SOA 11g you need to create partitions to logically group SOA composites. Partitions are similar to the BPEL 10g domains. You can perform bulk life-cycle management operations on all SOA composites deployed on a partition. In SOA 11g you need to set the entire configuration (audit level, threading etc) at SOA infrastructure level so you can not perform any BPEL Engine specific configuration tasks on partitions. Click here for more details on creating and managing partitions.
Deploy SOA Projects to Server and Test
Deploy SOA composites and test them to verify that the upgraded code is working as expected.
Tune SOA 11g Infrastructure
After verifying that the migrated and modified code is working as expected you can start performance tuning SOA 11g infrastructure. Click here for details about BPEL Engine properties. I will write on SOA 11g Performance tuning best practices in my next posts.
SOA 10g to 11g migration requires lot more to do than simply executing migration script/wizard. You need to carefully plan your upgrade strategy. You can use these best practices as a reference. In next series of blog posts I will write about best practices of upgrading other SOA 10g projects (ESB, BAM, Business Rules etc).


  1. Right-click soa-infra. in em console of soa 11g
  1. Above the Composite table, click Deploy.
·  The Select Archive page appears.
·  In the Archive or Exploded Directory section, specify the archive of the SOA composite application to deploy. The archive contains the project files of the composite to be deployed (for example, HelloWorld_rev1.0.jar for a single archive or OrderBooking_rev1.0.zip for multiple archives). This information is required.
·  In the Configuration Plan section, optionally specify the configuration plan to include with the archive. The configuration plan enables you to define the URL and property values to use in different environments. During process deployment, the configuration plan is used to search the SOA project for values that must be replaced to adapt the project to the next target environment.
·  Click Next.
The Select Target page appears.
This page lists the Oracle SOA Suite managed server or cluster to which to deploy the SOA composite application archive.
·  Select the partition into which to deploy this SOA composite application. Partitions enable you to logically group SOA composite applications into separate sections. Note that even if there is only one partition available, you must explicitly select it. Once deployed, a composite cannot be transferred to a different partition.
If you want to deploy to a partition that does not exist, exit the wizard and create the partition before deploying the composite. You create partitions in the Manage Partition page, accessible from the SOA Infrastructure menu.
If the server contains no partitions, you cannot deploy composite applications to that server. Also, if the server is not in a running state, you cannot deploy this archive. By default, a partition named default is automatically included with Oracle SOA Suite. You can delete the default partition.
Note:
Human workflow artifacts such as task mapped attributes (previously known as flex field mappings) and rules (such as vacation rules) are defined based on the namespace of the task definition. Therefore, the following issues are true when the same SOA composite application with a human workflow task is deployed into multiple partitions:
  • For the same task definition type, mapped attributes defined in one partition are visible in another partition.
  • Rules defined on a task definition in one partition can apply to the same definition in another partition.
If you invoke the Deploy SOA Composite wizard by selecting Deploy to This Partition from the Deployment dropdown list on the Manage Partitions page or home page of a specific partition, the partition to which to deploy is selected. Therefore, the Select Target page is skipped.
·  Click Next.
The Confirmation page appears.
·  Review your selections.
·  Select whether to deploy the SOA composite application as the default revision. The default revision is instantiated when a new request comes in.
·  Click Deploy.
Processing messages are displayed.
At this point, the deployment operation cannot be canceled. Deployment continues even if the browser window is closed.
·  When deployment has completed, the home page of the newly deployed composite revision is displayed automatically. A confirmation message at the top of the page tells you that the composite has been successfully deployed. In the case of a bundle deployment, the Deployed Composites page of the SOA Infrastructure is displayed.

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.