Thursday, October 27, 2011

Oracle SOA Suite – Getting the payload from the Composite instance through Java API - Part1


Oracle SOA Suite– Getting the payload from the Composite instance through Java API - Part1 

This blog explains the approach to retrieve the request payload from the closed composite instance.
The below code snippet will enable you to retrieve the request payload from the closed composite instance for Oracle SOA Suite 11g or Oracle SOA Suite 12c

import java.util.Hashtable;
import java.util.List;
import javax.naming.Context;
import oracle.soa.management.facade.ComponentInstance;
import oracle.soa.management.facade.CompositeInstance;
import oracle.soa.management.facade.Locator;
import oracle.soa.management.facade.LocatorFactory;
import oracle.soa.management.util.ComponentInstanceFilter;
import oracle.soa.management.util.CompositeInstanceFilter;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

public class GetCompositeInstancePayload {
    //Invoke this method with the composite instance id
    public static String getCompositeInstancePayload(String compInstanceId, String ecid) {
        String compositeName = "GetOpenCompositeInstances";
        Hashtable jndiProps = new Hashtable();
        String inputPayload = "";
        try {
            jndiProps.put(Context.PROVIDER_URL, "t3://localhost:7201");
            jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
            jndiProps.put(Context.SECURITY_PRINCIPAL, "weblogic");
            jndiProps.put(Context.SECURITY_CREDENTIALS, "Test1234");
            jndiProps.put("dedicated.connection", "true");
            Locator locator = LocatorFactory.createLocator(jndiProps);
            CompositeInstanceFilter filter = new CompositeInstanceFilter();
            filter.setECID(ecid); //Set the composite ECID
            List compositeInstance = locator.getCompositeInstances(filter);
            ComponentInstanceFilter instanceFilter = new ComponentInstanceFilter();
            instanceFilter.setCompositeInstanceId(compInstanceId);           
            List componentInstance =((CompositeInstance) compositeInstance.get(0)).getChildComponentInstances(instanceFilter);
            if (compositeInstance.size() > 0) {
                Document docAudit = XMLUtil.convertToDOM(((ComponentInstance) componentInstance.get(0)).getAuditTrail().toString());
                String payloadAudit = XPathUtils.executeXPath(docAudit, "//details").toString();
                Document docPayload = XMLUtil.convertToDOM(payloadAudit);
                Node payloadNode = XPathUtils.executeXPath(docPayload, "//part//*", "NODE");
                inputPayload = XMLUtil.nodeToString(payloadNode);
                System.out.println("InputPayload: "+ inputPayload);
            }
           
        } catch (Exception e) {
            e.printStackTrace();
        }
       
        return inputPayload;
    }

    public static void main(String[] args) {
       getCompositeInstancePayload("23","9897cfe2-ee70-44d6-9e40-9c77651c7025-00000783");
    }
}

XPathUtils:


Utility class to retrieve the XML payload from the instance audit trail.
import javax.xml.xpath.*;

import org.w3c.dom.*;

public class XPathUtils {
    public static Object executeXPath(Document doc, String xpathStr) throws Exception {
        XPath xpath = null;
        String value = null;
        try {
            xpath = new org.apache.xpath.jaxp.XPathFactoryImpl().newXPath();
            XPathExpression expr = xpath.compile(xpathStr);
            value = (String) expr.evaluate(doc, XPathConstants.STRING);
            return value;
        } catch (Exception e) {
            throw e;
        }
    }

    public static Node executeXPath(Document doc, String xpathStr, String type) throws Exception {
        XPath xpath = null;
        Node value = null;
        try {
            xpath = new org.apache.xpath.jaxp.XPathFactoryImpl().newXPath();
            XPathExpression expr = xpath.compile(xpathStr);
            value = (Node) expr.evaluate(doc, XPathConstants.NODE);
            return value;
        } catch (Exception e) {
            throw e;
        }
    }
}


XMLUtil:Utility class to convert the XML document to string.

import java.io.*;

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.*;

import org.xml.sax.InputSource;

public class XMLUtil {
    public static Document convertToDOM(String inputXML) throws Exception {
        Document dom = null;
        try {
            DocumentBuilder builder = new org.apache.xerces.jaxp.DocumentBuilderFactoryImpl().newDocumentBuilder();
            InputSource is = new InputSource(new StringReader(inputXML));
            dom = builder.parse(is);
        } catch (Exception ex) {
            throw ex;
        }
        return dom;
    }

    public static String nodeToString(Node node) throws Exception {
        StringWriter sw = new StringWriter();
        try {
            Transformer t = new org.apache.xalan.processor.TransformerFactoryImpl().newTransformer();
            t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            t.setOutputProperty(OutputKeys.INDENT, "yes");
            t.transform(new DOMSource(node), new StreamResult(sw));
        } catch (TransformerException te) {
            System.out.println("nodeToString Transformer Exception");
            throw te;
        }
        return sw.toString();
    }
}

Jar files -
$Oracle_Home\wlserver\server\lib\Wljmxclient.jar
$Oracle_Home\soa\soa\modules\oracle.soa.fabric_11.1.1\oracle.soa.fabric.jar
Xalan-2.7.2.jar
Xerces-2_6_2.jar
jrf-api.jar
Serializer-2.7.1.jar


The same approach will work in Oracle SOA Suite 12c

How to retrieve the ECID and component instance id in Oracle SOA Suite 12c:


Login to EM console
Click on Target Navigation - SOA - soa-infra
Click on Deployed Composites
Click on the Composite
Click on Flow Instances and click on Search
Open the Instance and Click on Show XML - the ECID and the component instance id can be copied from the XML

em_console_ecid_and_instanced

The ECID and Component instance id can be retrieved in another approach

Login to EM console
Click on Target Navigation - SOA - soa-infra
Click on Deployed Composites
Click on the Composite
Click on Flow Instances and click on Search
The table displays the ECID, if the ECID is not displayed then Click on View - Columns and select initiating ECID

em_console_ecid_and_instanced

Click on Instance and Select Show Instance IDs

em_console_ecid_and_instanced


10 comments:

  1. Useful post Albin. However, mine ended up in a SAXParserException. Are some changes to the xpath expression needed for individual cases?

    ReplyDelete
  2. no xpath change required for individual cases.

    I guess this issue could be because of class path issue.

    Provide me the full error stack so that i can try to look into that.

    Regards
    Albin I

    ReplyDelete
    Replies
    1. Albin,
      I am getting the following error while compiling the source:

      C:\>javac GetXMLPayload.java
      GetXMLPayload.java:43: cannot find symbol
      symbol : method getChildComponentInstances(oracle.soa.management.util.ComponentInstanceFilter)
      location: class java.lang.Object
      List componentInstance = compositeInstance.get(0).getChildComponentInstances(instanceFilter);
      ^
      GetXMLPayload.java:46: cannot find symbol
      symbol : method getAuditTrail()
      location: class java.lang.Object
      Document docAudit = XMLUtil.convertToDOM(componentInstance.get(0).getAuditTrail().toString());
      ^
      Note: GetXMLPayload.java uses unchecked or unsafe operations.
      Note: Recompile with -Xlint:unchecked for details.
      2 errors

      Does it require any libraries in the classpath?

      Thanks

      Delete
  3. Great post! I have found that the CompositeInstanceFilter doesn't perform as expected when I try setRevision("1.2"). I end up with both "1.2" revisions and "1.21" revisions of composite. Have you experienced this and do you have a suggestion to avoid the issue?

    ReplyDelete
    Replies
    1. Even i have faced the same issue anyhow for my scenario the issue has been resolved by setting filter.setId(compInstanceId);

      Delete
  4. We are trying to use this piece of code for reprocessing bulk orders however we face a problem in extracting the payload.

    It errors out "[Fatal Error] :1:1: Premature end of file." and on analysis, found that details attribute is missing in audit string for few interfaces. So xpath function is throwing the above error...
    How to counter such problems..? Any ideas will help us a lot...

    ReplyDelete
  5. I was looking for this exactly. Thanks for the useful post.

    I noticed that in some cases audit trail doesn't gives the instance payload at all in audit trail. However when you go and trace that bpel instance on em console there it retrieves the payload I don't know from where. Pasting here one sample audit trail where detail node is empty but on em console it gives the payload in trace.

















































    Look at 7th event node. Is there any solution/workaround for this issue?

    ReplyDelete
  6. Hello,

    I heard people talk about payload, but I don't know about it.
    Could you please tell me what kind of information we can get from payload and what is it used for? If possible, please give me the links to any useful documents that talk about it.

    many thanks in advance,
    sophea

    ReplyDelete
  7. Payload is nothing but a XML message revived by BPEL or send by BPEL to other partner systems invoked.

    In BPEL perspective all the XML message we will be calling as payload.

    Please let me know if you need more clarifications.

    Regards
    Albin I

    ReplyDelete
  8. Hi Albin,
    Thanks for an excellent post. I was looking exactly for this, and it worked in my case. However if the payload is too huge, the program fails to fetch. I noticed this happens when the payload is extremely big, say from em console to see the payload, one has to scroll and the server takes a pause to fetch remaining payload.

    I have 2 questions
    1. Is there a way to handle it in program to fetch such large payload?
    2. For knowledge purpose- curious to know where all you learned this stuff? especially picking and using the right APIs

    Thanks,
    Antony

    ReplyDelete