Wednesday, July 21, 2010

Soa Suite 11g - Fault recovery

Using the Oracle SOA Suite's Infrastructure Management Java API, it's possible to query the BPEL Engine for faults and recover this faults programmatically using the following Facades:
  • Locator: entry point to Facades API.
  • BPELServiceEngine: allows to query for faults, get and set variables data and recovery faults.
  • Fault: allows retrieve fault details information.
  • FaultRecoveryActionTypeConstants: contains Action constants used to recover faults.
To develop the Java code, create a new Java project in jDeveloper and import the following libs:
  • <middleware_home>/oracle_common/modules/oracle.fabriccommon_11.1.1/fabric-common.jar
  • <middleware_home>/jdeveloper/soa/modules/oracle.soa.mgmt_11.1.1/soa-infra-mgmt.jar
  • <middleware_home>/wlserver_10.3/server/lib/weblogic.jar
  • <middleware_home>/jdeveloper/soa/modules/oracle.soa.fabric_11.1.1/oracle-soa-client-api.jar
  • <middleware_home>/oracle_common/webservices/wsclient_extended.jar
The example below shows how to use the API to search for faults using filter, update variable data and do a Retry to recover the fault:
package br.inf.andrade.soasuite.faultRecovery;

import java.util.Hashtable;
import java.util.List;

import javax.naming.Context;

import oracle.soa.management.facade.Fault;
import oracle.soa.management.facade.FaultRecoveryActionTypeConstants;
import oracle.soa.management.facade.Locator;
import oracle.soa.management.facade.LocatorFactory;
import oracle.soa.management.facade.bpel.BPELServiceEngine;
import oracle.soa.management.util.FaultFilter;

public class FaultRecovery {

  private Locator locator = null;
  private BPELServiceEngine mBPELServiceEngine;

  public FaultRecovery() {
    locator = this.getLocator();
    try {
      mBPELServiceEngine =
          (BPELServiceEngine)locator.getServiceEngine(Locator.SE_BPEL);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public Hashtable getJndiProps() {
    Hashtable jndiProps = new Hashtable();
    jndiProps.put(Context.PROVIDER_URL,
                  "t3://soaserver11gr1ps2:8001/soa-infra");
    jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,
                  "weblogic.jndi.WLInitialContextFactory");
    jndiProps.put(Context.SECURITY_PRINCIPAL, "weblogic");
    jndiProps.put(Context.SECURITY_CREDENTIALS, "welcome1");
    jndiProps.put("dedicated.connection", "true");
    return jndiProps;
  }

  public Locator getLocator() {

    try {
      return LocatorFactory.createLocator(getJndiProps());
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  public void recoverFaults() {
    try {
      System.out.println("Get Recoverable Faults");

      /*
       * SEARCH FOR FAULTS
       */

      //Set filter according desired criteria
      FaultFilter filter = new FaultFilter();
      //filter.setCompositeDN("default/FaultClient!1.0");
      //filter.setCompositeInstanceId("40001");
      //filter.setComponentName("FaultClientProcess");
      //filter.setComponentInstanceId("bpel:40001");
      //filter.setId("default/FaultClient!1.0*soa_911ae0fd-c5ca-44ae-922c-6641a4e7d51f/FaultClientProcess/40001-BpInv0-BpSeq0.3-3");
      //filter.setFaultName("{http://xmlns.oracle.com/FaultRecovery_jws/FaultGenerator/FaultGeneratorProcess}BusinessFault");
      //filter.setLike("%<code>0001%");
      filter.setRecoverable(true);

      //Get faults using defined filter
      List<fault> faultList = mBPELServiceEngine.getFaults(filter);
      for (Fault fault : faultList) {
        System.out.println("=============================================================================================================");
        System.out.println("         Composite DN: " +
                           fault.getCompositeDN().getStringDN());
        System.out.println("Composite Instance ID: " +
                           fault.getCompositeInstanceId());
        System.out.println("       Component Name: " +
                           fault.getComponentName());
        System.out.println("Component Instance ID: " +
                           fault.getComponentInstanceId());
        System.out.println("        Activity Name: " + fault.getLabel());
        System.out.println("             Fault ID: " + fault.getId());
        System.out.println("           Fault Name: " + fault.getName());
        System.out.println("     Recoverable flag: " + fault.isRecoverable());
        System.out.println("        Fault Message: " + fault.getMessage());

        //Get fault variables
        String[] variables = mBPELServiceEngine.getVariableNames(fault);
        System.out.println("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+");
        System.out.println("Variables:");
        for (int i = 0; i < variables.length; i++) {
          System.out.println("* Name: " + variables[i]);
        }

        //Get operation input variable data, correct it and update the variable content
        System.out.println("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+");
        System.out.println("Operation Input Variable Data:");
        String value =
          mBPELServiceEngine.getVariable(fault, "invokeFaultGenerator_process_InputVariable");
        System.out.println("Old value: " + value);
        value = value.replace("BusinessFault", "Any string");
        System.out.println("New value: " + value);
        mBPELServiceEngine.setVariable(fault,
                                       "invokeFaultGenerator_process_InputVariable",
                                       value);

        //Retry each fault
        mBPELServiceEngine.recoverFault(fault,
                                        FaultRecoveryActionTypeConstants.ACTION_RETRY,
                                        null);
      }

      //Instead of recover each fault individually, you can recover all faults in a single API call
      //mBPELServiceEngine.recoverFaults(faultList.toArray(new Fault[faultList.size()]), FaultRecoveryActionTypeConstants.ACTION_RETRY);


    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    FaultRecovery faultRecovery = new FaultRecovery();
    faultRecovery.recoverFaults();
  }
}
To download this source code together with 2 SOA Composites to simulate a Business Fault, click here.