Wednesday 23 March 2011

Continuous Integration with Hudson

This blog will give you clear idea on automated deployment of SOA projects from subversion.Here is the scenario in brief,

Developed the code using Jdeveloper –> Checked in subversion –> Hudson will poll in subversion repository for any change –>On any change it will build and deploy the code in SOA server without any manual intervention –> After deployment status mail will be sent to the group.

To achieve that you have to follow couple of steps,

  1. Installing Hudson to your SOA server.

You can download hudson.war file from http://hudson-ci.org/.

In the directory where you saved hudson.war create a new directory called WEB-INF and inside that a file called weblogic.xml.  Here is the contents for the file:

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app
xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app">
<container-descriptor>
<prefer-application-packages>
<package-name>org.apache.*</package-name>
<package-name>org.dom4j.*</package-name>
</prefer-application-packages>
</container-descriptor>
</weblogic-web-app>

Now you need to add this file into the hudson.war using the following command:

# jar uvf hudson.war WEB-INF/weblogic.xml
Login to weblogic console and deploy the war file pointing soa_server as target.
Now the hudson page should be accessible by,
http://<host>:<port>/hudson.

Just click on enable auto refresh on top right corner.


2. Configure your Gmail account (can be any account) in your SOA server


You need to download openssl from http://www.openssl.org/related/binaries.html site.


Get gmail certificate by issuing openssl s_client -connect smtp.gmail.com:465 > smtp.cert command.


Edit smtp.cert remove everything except the :
—–BEGIN CERTIFICATE—–
<certificate>
—–END CERTIFICATE—–


Import the certificate into a new trust store by keytool -import -alias smtp.gmail.com -keystore trusted-certificates.jks -file smtp.cert.


Edit setDomainEnv.cmd, replace the existing javax.net.ssl.trustStore property setting with “-Djavax.net.ssl.trustStore=<path>/trusted-certificates.jks -Djavax.net.ssl.trustStorePassword=<password you used>” like in my case,


set EXTRA_JAVA_PROPERTIES=%EXTRA_JAVA_PROPERTIES% -Dsoa.archives.dir=%SOA_ORACLE_HOME%\soa -Dsoa.oracle.home=%SOA_ORACLE_HOME% -Dsoa.instance.home=%DOMAIN_HOME% -Dtangosol.coherence.clusteraddress=227.7.7.9 -Dtangosol.coherence.clusterport=9778 -Dtangosol.coherence.log=jdk -Djavax.xml.soap.MessageFactory=oracle.j2ee.ws.saaj.soap.MessageFactoryImpl -Dweblogic.transaction.blocking.commit=true -Dweblogic.transaction.blocking.rollback=true -Djavax.net.ssl.trustStore=C:\shrik\Oracle\fmw\user_projects\domains\base_domain\config\fmwconfig\trusted-certificates.jks -Djavax.net.ssl.trustStorePassword=changeit


Bounce the server.


Go to em,


image


and enter the following properties accordingly,


image


Then go to workflow notification property and set the notification mode email with proper from address,actionable address and reply to address.


image


Bounce the server once again and go to manage hudson from the left menu.


image


Then click on configure system and go to E-mail notification section and give all the values accordingly,


image


Click on test configuarion and you should get a test mail in your account.


3. Setting up version control system


I downloaded subversion server and client but you can download any CVS or other repository as well.


For testing purpose I would recommend VisualSVNServerManager at http://www.visualsvn.com/server/ and tortoise svn client at http://tortoisesvn.net/downloads.html .


In your ant deployment folder find the executable batch file will be picked up by Hudson for build and deployment if any change occur in the repository in my case its deployAll.bat,please check http://shrikworld.blogspot.com/2011/03/deploying-soa-11g-application-using-ant.html


You may need to copy ant-contrib.jar file from <fmw_home>\modules\net.sf.antcontrib_1.1.0.0_1-0b2\lib folder to Jdeveloper’s and SOA server’s <AntHome>/lib directory.



4. Create a JOB in Hudson


Go to http://shreekanta-pc:7001/hudson/ and click on create a new job on left menu,


image


Now click on the job and go to the configure section from left menu.


In the source code management you need to provide your repository URL like,


image


In Build Trigger select poll SCM and put ***** in schedule so that Hudson will poll SCM in every minute for any change.


In the Build section fill all as below,


image


In Post Build section give your account name accordingly,


image


Click on Save and enable auto refresh.


image


Change/Add any file in your subversion and Hudson will pick up and deploy the code into SOA server.


After that it will sent the status mail as per your account configuration.

Deploying SOA 11g Application using ANT

This blog will guide you the deploy SOA applications using ANT script.

Here is my subversion directory structure,

image

Under applications you put your application and projects underneath,

image

You might have several projects, in my case I’ve two projects BusinessEventTest and HelloWorldEmail.Every project has got its own deployment plan for different environments like in my case BusinessEventTest_cfgplan_dev.xml and HelloWorldEmail_cfgplan_dev.xml.

Create a build.properties file under applications and fill accordingly as below,

image

Give the partition name where you want to deploy.

Go back and under tools you should have following files,

image

In build.properties give the below information,

*****************************************************************************

# global
fmw.home=C:/shrik/Oracle/fmw
oracle.home=${fmw.home}/jdeveloper
java.passed.home=C:/shrik/Oracle/SOAWork/composites/jrockit
wl_home=${fmw.home}/wlserver_10.3

# temp
tmp.output.dir=c:/temp
junit.output.dir=../../

applications.home=../../applications
applications=HelloWorld

mds.enabled=false
mds.reposistory=${oracle.home}/integration/seed/apps/
mds.applications=Woningnet-Test
mds.undeploy=false

deployment.plan.environment=dev

# dev deployment server weblogic
dev.serverURL=http://shreekanta-pc:7001
dev.overwrite=true
dev.user=weblogic
dev.password=welcome1
dev.forceDefault=true
dev.server=shreekanta-pc
dev.port=7001

In dev.jndi.properties give the below information,

java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
java.naming.provider.url=t3://shreekanta-pc:7001/soa-infra
java.naming.security.principal=weblogic
java.naming.security.credentials=welcome1
dedicated.connection=true
dedicated.rmicontext=true

****************************************************************************

build.xml file ,you can use as it is else can customize as per your need,

***************************************************************************

<?xml version="1.0" encoding="iso-8859-1"?>
<project name="soaDeployAll" default="deployAll">
    <echo>basedir ${basedir}</echo>

    <property environment="env"/>
    <echo>current folder ${env.CURRENT_FOLDER}</echo>

    <property file="${env.CURRENT_FOLDER}/build.properties"/> 

    <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>


    <target name="deployAll">
         <if>
          <equals arg1="${mds.enabled}" arg2="true"/>
          <then>
             <antcall target="deployMDS" inheritall="true"/>
          </then>
      </if>     
      <foreach list="${applications}" param="application" target="deployApplication" inheritall="true" inheritrefs="false"/>
    </target>


    <target name="unDeployMDS">
        <echo>undeploy MDS</echo>
        <foreach list="${mds.applications}" param="mds.application" target="undeployMDSApplication" inheritall="true" inheritrefs="false"/>
    </target>

    <target name="deployMDS">
        <echo>undeploy and deploy MDS</echo>
        <if>
          <equals arg1="${mds.undeploy}" arg2="true"/>
          <then>
            <foreach list="${mds.applications}" param="mds.application" target="undeployMDSApplication" inheritall="true" inheritrefs="false"/>
          </then>
        </if>
        <foreach list="${mds.applications}" param="mds.application" target="deployMDSApplication" inheritall="true" inheritrefs="false"/>
    </target>

    <target name="deployMDSApplication">
        <echo>deploy MDS application ${mds.application}</echo>

        <echo>remove and create local MDS temp</echo>
        <property name="mds.deploy.dir" value="${tmp.output.dir}/${mds.application}"/>
               
        <delete dir="${mds.deploy.dir}"/>
        <mkdir dir="${mds.deploy.dir}"/>

        <echo>create zip from file MDS store</echo>
            <zip destfile="${mds.deploy.dir}/${mds.application}_mds.jar" compress="false">
              <fileset dir="${mds.reposistory}" includes="${mds.application}/**"/>
            </zip>

        <echo>create zip with MDS jar</echo>
            <zip destfile="${mds.deploy.dir}/${mds.application}_mds.zip" compress="false">
              <fileset dir="${mds.deploy.dir}" includes="*.jar"/>
            </zip>

        <propertycopy name="deploy.serverURL"    from="${deployment.plan.environment}.serverURL"/>
        <propertycopy name="deploy.overwrite"    from="${deployment.plan.environment}.overwrite"/>
        <propertycopy name="deploy.user"         from="${deployment.plan.environment}.user"/>
        <propertycopy name="deploy.password"     from="${deployment.plan.environment}.password"/>
        <propertycopy name="deploy.forceDefault" from="${deployment.plan.environment}.forceDefault"/>

        <echo>deploy MDS app</echo>

        <echo>deploy on ${deploy.serverURL} with user ${deploy.user}</echo>
        <echo>deploy sarFile ${mds.deploy.dir}/${mds.application}_mds.zip</echo>

        <ant antfile="${oracle.home}/bin/ant-sca-deploy.xml" inheritAll="false" target="deploy">
             <property name="wl_home" value="${wl_home}"/>
             <property name="oracle.home" value="${oracle.home}"/>
             <property name="serverURL" value="${deploy.serverURL}"/>
             <property name="user" value="${deploy.user}"/>
             <property name="password" value="${deploy.password}"/>
             <property name="overwrite" value="${deploy.overwrite}"/>
             <property name="forceDefault" value="${deploy.forceDefault}"/>
             <property name="sarLocation" value="${mds.deploy.dir}/${mds.application}_mds.zip"/>
        </ant>     
    </target>

    <target name="undeployMDSApplication">
        <echo>undeploy MDS application ${mds.application}</echo>

        <propertycopy name="deploy.serverURL"    from="${deployment.plan.environment}.serverURL"/>
        <propertycopy name="deploy.overwrite"    from="${deployment.plan.environment}.overwrite"/>
        <propertycopy name="deploy.user"         from="${deployment.plan.environment}.user"/>
        <propertycopy name="deploy.password"     from="${deployment.plan.environment}.password"/>
        <propertycopy name="deploy.forceDefault" from="${deployment.plan.environment}.forceDefault"/>

         <echo>undeploy MDS app folder apps/${mds.application} </echo>
         <ant antfile="${oracle.home}/bin/ant-sca-deploy.xml" inheritAll="false" target="removeSharedData">
                 <property name="wl_home" value="${wl_home}"/>
              <property name="oracle.home" value="${oracle.home}"/>
              <property name="serverURL" value="${deploy.serverURL}"/>
              <property name="user" value="${deploy.user}"/>
              <property name="password" value="${deploy.password}"/>
                 <property name="folderName" value="${mds.application}"/>
         </ant>   
    </target>


    <target name="deployApplication">
        <echo>deploy application ${application}</echo>
        <property file="${env.CURRENT_FOLDER}/${applications.home}/${application}/build.properties"/>  
        <foreach list="${projects}" param="project" target="deployProject" inheritall="true" inheritrefs="false"/>
    </target>
   
    <target name="deployProject">
        <echo>deploy project ${project} for  environment ${deployment.plan.environment}</echo>

        <property name="proj.compositeName" value="${project}"/>
        <property name="proj.compositeDir" value="${env.CURRENT_FOLDER}/${applications.home}/${application}"/>
        <propertycopy name="proj.revision" from="${project}.revision"/>
        <propertycopy name="proj.enabled" from="${project}.enabled"/>
        <propertycopy name="proj.partition" from="${project}.partition"/>
       
       
        <echo>deploy compositeName ${proj.compositeName}</echo>
        <echo>deploy compositeDir ${proj.compositeDir}</echo>


         <ant antfile="${oracle.home}/bin/ant-sca-package.xml" inheritAll="false" target="package">
             <property name="compositeDir" value="${proj.compositeDir}/${project}"/>
             <property name="compositeName" value="${proj.compositeName}"/>
             <property name="revision" value="${proj.revision}"/>
             <property name="oracle.home" value="${oracle.home}"/>
             <property name="java.passed.home" value="${java.passed.home}"/>
             <property name="wl_home" value="${wl_home}"/>
             <property name="sca.application.home" value="${proj.compositeDir}"/>
             <property name="scac.application.home" value="${proj.compositeDir}"/>
             <property name="scac.input" value="${proj.compositeDir}/${proj.compositeName}/composite.xml"/>
             <property name="scac.output" value="${tmp.output.dir}/${proj.compositeName}.xml"/>
             <property name="scac.error" value="${tmp.output.dir}/${proj.compositeName}.err"/>
             <property name="scac.displayLevel" value="3"/>
        </ant>   

        <property name="deploy.sarLocation" value="${proj.compositeDir}/${proj.compositeName}/deploy/sca_${proj.compositeName}_rev${proj.revision}.jar"/>
        <property name="deploy.configplan"  value="${proj.compositeDir}/${proj.compositeName}/${proj.compositeName}_cfgplan_${deployment.plan.environment}.xml"/>

        <propertycopy name="deploy.serverURL"    from="${deployment.plan.environment}.serverURL"/>
        <propertycopy name="deploy.overwrite"    from="${deployment.plan.environment}.overwrite"/>
        <propertycopy name="deploy.user"         from="${deployment.plan.environment}.user"/>
        <propertycopy name="deploy.password"     from="${deployment.plan.environment}.password"/>
        <propertycopy name="deploy.forceDefault" from="${deployment.plan.environment}.forceDefault"/>
        <propertycopy name="deploy.server"       from="${deployment.plan.environment}.server"/>
        <propertycopy name="deploy.port"         from="${deployment.plan.environment}.port"/>

        <echo>deploy on ${deploy.serverURL} with user ${deploy.user}</echo>
        <echo>deploy sarFile ${deploy.sarLocation}</echo>


         <ant antfile="${oracle.home}/bin/ant-sca-deploy.xml" inheritAll="false" target="deploy">
             <property name="wl_home" value="${wl_home}"/>
             <property name="oracle.home" value="${oracle.home}"/>
             <property name="serverURL" value="${deploy.serverURL}"/>
             <property name="partition" value="${proj.partition}"/>
             <property name="user" value="${deploy.user}"/>
             <property name="password" value="${deploy.password}"/>
             <property name="overwrite" value="${deploy.overwrite}"/>
             <property name="forceDefault" value="${deploy.forceDefault}"/>
             <property name="sarLocation" value="${deploy.sarLocation}"/>
             <property name="configplan" value="${deploy.configplan}"/>
        </ant>   

       <echo>disable or enable composite ${proj.compositeName} </echo>
                   
        <if>
          <equals arg1="${proj.enabled}" arg2="false"/>
          <then>
            <ant antfile="${oracle.home}/bin/ant-sca-mgmt.xml" inheritAll="false" target="stopComposite">
                  <property name="host" value="${deploy.server}"/>
                  <property name="port" value="${deploy.port}"/>
                  <property name="user" value="${deploy.user}"/>
                  <property name="password" value="${deploy.password}"/>
                  <property name="compositeName" value="${proj.compositeName}"/>
                  <property name="revision" value="${proj.revision}"/>
                  <property name="partition" value="${proj.partition}"/>
            </ant>   

          </then>
        </if>

        <if>
          <equals arg1="${proj.enabled}" arg2="true"/>
          <then>
            <ant antfile="${oracle.home}/bin/ant-sca-mgmt.xml" inheritAll="false" target="activateComposite">
                  <property name="host" value="${deploy.server}"/>
                  <property name="port" value="${deploy.port}"/>
                  <property name="user" value="${deploy.user}"/>
                  <property name="password" value="${deploy.password}"/>
                  <property name="compositeName" value="${proj.compositeName}"/>
                  <property name="revision" value="${proj.revision}"/>
                  <property name="partition" value="${proj.partition}"/>
            </ant>   
       
            <echo>unit test sarFile ${proj.compositeName} </echo>

            <ant antfile="${oracle.home}/bin/ant-sca-test.xml" inheritAll="false" target="test">
                 <property name="scatest.input" value="${project}"/>
                 <property name="scatest.format" value="junit"/>
                 <property name="scatest.result" value="${env.CURRENT_FOLDER}/${junit.output.dir}"/>
                 <property name="scatest.partition" value="${proj.partition}"/>
                 <property name="jndi.properties.input" value="${deployment.plan.environment}.jndi.properties"/>
            </ant>   

          </then>
        </if>       
       
        
    </target>
   
</project>

**********************************************************************************

At last deployAll.bat file would have following entries,

image

Open a command prompt and execute deployAll which will deploy all your projects under a particular application in SOA Server.

Saturday 5 March 2011

ErrorHandling in SOA 11g

In SOA 11g we can go for common error handling approach to capture fault at component and composite level.In this test cases I’ve one HelloWorld bpel process ,just prints hello.We cave another parent process,CallHelloWorldComposite that calls Hello process and here we’ll implement the fault policy.

To implement the Error Handler we need fault-policies.xml and fault-bindings.xml file.You can access those files locally from your project folder as well as from MDS or some other places.

image

Here in this case policies files are there in local project folder and in this case you need to just create those file and no entry in composite.xml is required.

But to access fault policy file from other places you need to add below properties in composite.xml,In this case I added policy at composite level.

image

You can give full path of either directory structure or MDS path in those values.

Now we need to design fault-policies.xml file to capture all kind of faults and actions need to be taken if error occurred.You can add your custom java code to perform any additional task like send email notification or enqueing data into custom error queue.Here is my fault-policies.xml file,

*******************************************************************************

<?xml version="1.0" encoding="UTF-8" ?>
<faultPolicies xmlns="http://schemas.oracle.com/bpel/faultpolicy">
  <faultPolicy version="2.0.1" id="commonErrorHandler"
               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:bpelx="http://schemas.oracle.com/bpel/extension"
                 name="bpelx:remoteFault">
   
        <condition>
          <action ref="ora-retry"/>
        </condition>
      
     
      </faultName>
      <faultName xmlns:medns="http://schemas.oracle.com/mediator/faults"
                 name="medns:mediatorFault">
        <condition>
          <action ref="ora-cust"/>
        </condition>
      </faultName>
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
                 name="bpelx:bindingFault">
        <condition>
          <action ref="ora-errorQ"/>
        </condition>
      </faultName>
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
                 name="bpelx:runtimeFault">
        <condition>
          <action ref="ora-errorQ"/>
        </condition>
      </faultName>
    </Conditions>
    <Actions>
      <Action id="ora-terminate">
        <abort/>
      </Action>
      <Action id="ora-rethrow-fault">
        <rethrowFault/>
      </Action>
      <Action id="ora-replay-scope">
        <replayScope/>
      </Action>
      <Action id="ora-human-intervention">
        <humanIntervention/>
      </Action>
      <Action id="ora-retry">
        <retry>
          <retryCount>3</retryCount>
          <retryInterval>2</retryInterval>
          <exponentialBackoff/>
          <retryFailureAction ref="send-notification"/>
          <retrySuccessAction ref="ora-errorQ"/>
        </retry>
      </Action>
      <Action id="ora-cust">
        <javaAction className="com.shrik.TestJavaAction"
                    defaultAction="ora-terminate"
                    propertySet="send-notification-properties">
          <returnValue value="REPLAY" ref="ora-terminate"/>
          <returnValue value="RETRHOW" ref="ora-rethrow-fault"/>
          <returnValue value="ABORT" ref="ora-terminate"/>
          <returnValue value="RETRY" ref="ora-retry"/>
          <returnValue value="MANUAL" ref="ora-human-intervention"/>
        </javaAction>
      </Action>
      <Action id="ora-errorQ">
        <javaAction className="com.shrik.ErrorHospitalQueue"
                    defaultAction="ora-terminate"
                    propertySet="enqueue-properties">
          <returnValue value="REPLAY" ref="ora-terminate"/>
          <returnValue value="RETRHOW" ref="ora-rethrow-fault"/>
          <returnValue value="ABORT" ref="ora-terminate"/>
          <returnValue value="RETRY" ref="ora-retry"/>
          <returnValue value="MANUAL" ref="ora-human-intervention"/>
        </javaAction>
      </Action>
      <Action id="send-notification">
        <javaAction className="com.shrik.ErrorHospitalNotification"
                    defaultAction="ora-human-intervention"
                    propertySet="send-notification-properties">
          <returnValue value="MANUAL" ref="ora-human-intervention"/>
        </javaAction>
      </Action>
    </Actions>
    <!-- Property sets used by custom Java actions -->
    <Properties>
      <propertySet name="send-notification-properties">
        <property name="from"><Give from address></property>
        <property name="to"><Give To Address></property>
        <property name="subject">Test Mail</property>
        <property name="text">Environment: TEST</property>
        <property name="host"><smtp host server></property>
        <property name="port"><smtp port></property>
        <property name="username"><user name></property>
        <property name="password"><password></property>
      </propertySet>
      <propertySet name="enqueue-properties">
        <property name="aq.queueconnectionfactory">aqjms/XAQueueConnectionFactory</property>
          <property name="aq.queue">jms/errorQ</property>
      </propertySet>
    </Properties>
  </faultPolicy>
</faultPolicies>
****************************************************************************************

and here is my fault-bindings.xml file,

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


****************************************************************************************

If HelloWorld endpoint is unreachable then  bpelx:remoteFault will happen and as per fault policy it will execure ora-retry action,will try to retry the endpoint 3 times in 2,4,8 seconds intervals and upon subsequent failure it will invoke com.shrik.ErrorHospitalNotification class with send-notification-properties to notify faults to users.

To write your custom java code,create a new project like,

image

in this project we need to import some jars from <OracleMiddlewareHome>/Oracle_SOA1/soa/modules/oracle.soa.bpel_11.1.1 ,oracle.soa.fabric_11.1.1 directory.

For my case here is the code excerpt ,

For sending email notification from fault policy(ErrorHospitalNotification.java),

****************************************************************************************

package com.shrik;

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


import java.util.ArrayList;
import java.util.Map;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import oracle.integration.platform.faultpolicy.IFaultRecoveryContext;
import oracle.integration.platform.faultpolicy.IFaultRecoveryJavaClass;


public class ErrorHospitalNotification implements IFaultRecoveryJavaClass {
    private String from;
    private String to;
    private String subject;
    private String text;
    private String host;
    private String port;
    private String username;
    private String password;
    private Properties props;

    public ErrorHospitalNotification() {
        super();
    }

    private void sendMail() {
        props = new Properties();
        props.put("mail.smtp.host", getHost());
        props.put("mail.smtp.port", getPort());
        props.put("mail.transport.protocol", "smtp");
        props.setProperty("mail.smtps.quitwait", "false");
        props.put("mail.smtp.auth", "true");
        Authenticator auth = new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(getUsername(),
                                                  getPassword());
            }
        };
        Session mailSession = Session.getDefaultInstance(props, auth);
        Message simpleMessage = new MimeMessage(mailSession);
        try {
            InternetAddress fromAddress = new InternetAddress(from);
            simpleMessage.setFrom(fromAddress);
            String toAddresses[] = to.split(";");
            if (toAddresses != null && toAddresses.length > 0) {
                InternetAddress toInternetAddresses[] =
                    new InternetAddress[toAddresses.length];
                for (int i = 0; i < toAddresses.length; i++)
                    toInternetAddresses[i] =
                            new InternetAddress(toAddresses[i]);

                simpleMessage.setRecipients(javax.mail.Message.RecipientType.TO,
                                            toInternetAddresses);
            }
            simpleMessage.setSubject(subject);
            simpleMessage.setText(text);
            Transport.send(simpleMessage);
        } catch (AddressException e) {
            System.out.println("Error formatting Internet Email Address: " +
                               e.getMessage().toString());
            e.printStackTrace();
        } catch (MessagingException e) {
            System.out.println("Error sending email: " +
                               e.getMessage().toString());
            e.printStackTrace();
        }
    }

    private String getParameterValue(ArrayList parameterList) {
        String value = null;
        if (parameterList != null && parameterList.size() > 0)
            value = (String)parameterList.get(0);
        return value;
    }

    public void handleRetrySuccess(IFaultRecoveryContext iFaultRecoveryContext) {
        BPELFaultRecoveryContextImpl bpelCtx =
            (BPELFaultRecoveryContextImpl)iFaultRecoveryContext;
        Map properties = iFaultRecoveryContext.getProperties();
        if (properties != null && properties.size() == 8) {
            setFrom(getParameterValue((ArrayList)properties.get("from")));
            setTo(getParameterValue((ArrayList)properties.get("to")));
            setSubject(getParameterValue((ArrayList)properties.get("subject")) +
                       " " + "Retry Success");
            setText("The exception that occurred when processing " +
                    bpelCtx.getTitle() + " was successfully retried.\n" +
                    "This message was automatically generated, please do not reply to it.");
            setHost(getParameterValue((ArrayList)properties.get("host")));
            setPort(getParameterValue((ArrayList)properties.get("port")));
            setUsername(getParameterValue((ArrayList)properties.get("username")));
            setPassword(getParameterValue((ArrayList)properties.get("password")));
            sendMail();
        }
    }


    public String handleFault(IFaultRecoveryContext iFaultRecoveryContext) {
        Map properties = iFaultRecoveryContext.getProperties();

        BPELFaultRecoveryContextImpl bpelCtx =
            (BPELFaultRecoveryContextImpl)iFaultRecoveryContext;

        if (properties != null && properties.size() == 8) {
            setFrom(getParameterValue((ArrayList)properties.get("from")));
            setTo(getParameterValue((ArrayList)properties.get("to")));
            setSubject(getParameterValue((ArrayList)properties.get("subject")) +
                       bpelCtx.getTitle());
            setText(getParameterValue((ArrayList)properties.get("text")) +
                    "BPEL Process Instance: " + bpelCtx.getInstanceId() +
                    " needs intervention to recover from a technical exception: " +
                    bpelCtx.getFault().getMessage() +
                    "Check the Activities tab in the BPEL Management Console in order to resolve the error as soon as possible. This message was automatically generated, please do not reply to it.");
            setHost(getParameterValue((ArrayList)properties.get("host")));
            setPort(getParameterValue((ArrayList)properties.get("port")));
            setUsername(getParameterValue((ArrayList)properties.get("username")));
            setPassword(getParameterValue((ArrayList)properties.get("password")));
            bpelCtx.addAuditTrailEntry("Sending Email...");
            sendMail();
        }

        return "MANUAL";
    }


    public void setFrom(String from) {
        this.from = from;
    }

    public String getFrom() {
        return from;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public String getTo() {
        return to;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getSubject() {
        return subject;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getHost() {
        return host;
    }

    public void setPort(String port) {
        this.port = port;
    }

    public String getPort() {
        return port;
    }

    public void setProps(Properties props) {
        this.props = props;
    }

    public Properties getProps() {
        return props;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUsername() {
        return username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }

}

****************************************************************************************

Now your custom java code should be referenced by weblogic server,For that,

  1. Create a jar file containing all your custom java code.
  2. Place the jar file in <OracleMiddlewareHome>/Oracle_SOA1/soa/modules/oracle.soa.ext_11.1.1 directory.
  3. Make sure ANT/bin is set in your classpath.
  4. and just run ant from that directory and eventually it will generate oracle.soa.ext.jar file.
  5. Start the weblogic server.

Now deploy the HelloWorld and caller process and turn helloworld endpoint off from em.

Now when you run CallHelloWorldComposite then definitely it will throw remote fault and parse your fault policy file.

After retrying it will send notification and go to manual intervention for recovery.

You can extend your Error Handling Framework as per your project need.