How to Recover Initial Messages (Payload) from SOA Audit for Mediator and BPEL components

Introduction

In Fusion Applications, the status of SOA composite instances are either running, completed, faulted or staled. The composite instances become staled immediately (irrespective of current status) when the respective composite is redeployed with the same version. The messages (payload) are stored in SOA audit tables until they are purged. The users can go through Enterprise Manager and view audit trails and respective messages of each composite. This is good for debugging composite instances. However there are situations where you want to re-submit initiation of SOA composite instances in bulk for the following reasons:

  • The composite was redeployed with the same version number that resulted in all respective instances (completed successfully, faulted or in-flight) becoming stale (“Staled” status)
  • Instances failed because down-stream applications failed and the respective composite did not have an ability to capture the initial message in persistence storage to retry later

In these cases, it may be necessary to capture the initial message (payload) of many instances in bulk to resubmit them. This can be managed programmatically through SOA Facade API. The Facade API is part of Oracle SOA Suite’s Infrastructure Management Java API that exposes operations and attributes of composites, components, services, references and so on. As long as instances are not purged, the developer can leverage SOA Facade API to retrieve initial messages of either Mediator or BPEL components programmatically. The captured messages can be either resubmitted immediately or stored in persistence storage, such as file, jms or database, for later submission. There are several samples, but this post takes the approach of creating a SOA composite that provides the ability to retrieve initial message of Mediator or BPEL components. The sample provides the frame work and you can tailor it to your requirements.

Main Article

SOA Facade API

Please refer to this for complete SOA Facade API documentation. The SOA audit trails and messages work internally as follows:

  • The “Audit Level” should be either Production or Development to capture the initial payload
  • The “Audit Trail Threshold” determines the location of the initial payload.  If the threshold is exceeded, the View XML link is shown in the audit trail instead of the payload. The default value is 50,000 bytes. These large payloads are stored in a separate database table: audit_details.

Please refer to the following document for more details on these properties.

Since the SOA composite we are developing will be deployed in the same respective SOA Server, you do not require user credentials to create the locator object. This is all you need:

Locator locator = LocatorFactory.createLocator();

Please see the SOA Facade API document for more information the Locator class.

Once the Locator object is created, you can lookup composites and apply various filters to narrow down the search to respective components. This is all explained in detail with examples in the SOA Facade document. Here, we focus on how to retrieve the initial messages of the Mediator and BPEL components to resubmit them.

How to retrieve initial payload from BPEL?

In BPEL, the initial payload is either embedded in the audit trail or has a link to it. This is controlled by the audit trail threshold value. If the payload size exceeds the audit threshold value then the audit trail has a link. This is the main method to get audit trail:

auditTrailXml = (String)compInst.getAuditTrail
/* The “compInst” is an instance Component that is derived from: */
Component lookupComponent = (Component)locator.lookupComponent(componentName);
ComponentInstanceFilter compInstFilter = new ComponentInstanceFilter(); compInstFilter.setId(componentId);

 

If the payload size exceeds the audit threshold value, then the actual payload is an XML link that is stored in the “audit_details” table. The following is the API facade to get it:

auditDetailXml = (String)locator.executeComponentInstanceMethod(componentType +”:”+ componentId, auditMethod, new String[]{auditId});

The “auditId” for SOA is always “0”.

 

How to retrieve initial payload from Mediator

The initial payload in Mediator is never embedded in the Audit Trail. It is always linked and the syntax is similar to BPEL (where payload size exceeds the audit threshold value). However, the “auditID” is in the Mediator audit trail and it must be parsed to get that value for the initial payload. This is the code snippet to get the “auditId” from Mediator audit trail:

if (componentType.equals("mediator")) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(new InputSource(new StringReader(auditTrailXml)));
NodeList nodeList = document.getElementsByTagName("event");
String attribute = nodeList.item(0).getAttributes().getNamedItem("auditId").getNodeValue();
addAuditTrailEntry("The Audit is: " + attribute); 
auditId = attribute;auditMethod="getAuditMessage";} 

/* Once you have the "auditID" from above code, the syntax to get the initial payload is the same as in BPEL.*/
auditDetailXml = (String)locator.executeComponentInstanceMethod(componentType +":"+ componentId, auditMethod, new String[]{auditId});

 

Complete Java embedded code in BPEL

try { 
String componentInstanceID = new Long(getInstanceId()).toString();    
addAuditTrailEntry("This Run time Component Instance ID is "+componentInstanceID);  

XMLElement compositeNameVar = (XMLElement) getVariableData("inputVariable", "payload", "/client:process/client:compositeName");
String compositeName = compositeNameVar.getTextContent();  

XMLElement compositeIdVar = (XMLElement) getVariableData("inputVariable", "payload", "/client:process/client:compositeId");
String compositeId = compositeIdVar.getTextContent();  

XMLElement componentTypeVar = (XMLElement) getVariableData("inputVariable", "payload", "/client:process/client:componentType");
String componentType = componentTypeVar.getTextContent();  

XMLElement componentNameVar = (XMLElement) getVariableData("inputVariable", "payload", "/client:process/client:componentName");
String componentName = componentNameVar.getTextContent();  

XMLElement componentIdVar = (XMLElement) getVariableData("inputVariable", "payload", "/client:process/client:componentId");
String componentId = componentIdVar.getTextContent();  

String auditDetailXml = "null";
String auditTrailXml = "null";
String auditMethod = "getAuditDetails";
String auditId = "0";

addAuditTrailEntry("The lookup Composite Instance Name is "+compositeName);  
addAuditTrailEntry("The lookup Composite Instance ID is "+compositeId);  
addAuditTrailEntry("The lookup Component Instance Name is "+componentName);
addAuditTrailEntry("The lookup Component Instance Type is " + componentType);
addAuditTrailEntry("The lookup Component Instance ID is "+componentId);  

Locator locator = LocatorFactory.createLocator();  
Composite composite = (Composite)locator.lookupComposite(compositeName);  
Component lookupComponent = (Component)locator.lookupComponent(componentName);  

ComponentInstanceFilter compInstFilter = new ComponentInstanceFilter();  

compInstFilter.setId(componentId);

List<ComponentInstance> compInstances = lookupComponent.getInstances(compInstFilter);  
if (compInstances != null) {  
    addAuditTrailEntry("====Audit Trail of Instance===");  
    for (ComponentInstance compInst : compInstances) {  
        String compositeInstanceId = compInst.getCompositeInstanceId(); 
        String componentStatus = compInst.getStatus(); 
        addAuditTrailEntry("Composite Instance ID is "+compositeInstanceId);  
        addAuditTrailEntry("Component Status is "+componentStatus);  

        addAuditTrailEntry("Get Audit Trail");
        auditTrailXml = (String)compInst.getAuditTrail();

        if (componentType.equals("mediator")) {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document document = db.parse(new InputSource(new StringReader(auditTrailXml)));
            NodeList nodeList = document.getElementsByTagName("event");
            String attribute = nodeList.item(0).getAttributes().getNamedItem("auditId").getNodeValue();
            addAuditTrailEntry("The Audit is: " + attribute);

            auditId = attribute;
            auditMethod="getAuditMessage";
            }

        addAuditTrailEntry("Received Audit Trail");

        addAuditTrailEntry("Get Audit Details of: "+ componentType +":"+ componentId + "for auditId: " + auditId);

        try {
            auditDetailXml = (String)locator.executeComponentInstanceMethod(componentType +":"+ componentId, auditMethod, new String[]{auditId});
        } catch (Exception e) { 
        addAuditTrailEntry("Exception in getting audit details:" + e);
        }

        addAuditTrailEntry("Received Audit Details");

        setVariableData("auditTrailString", "payload", "/client:AuditTrailString/client:auditTrail", auditTrailXml);
        setVariableData("auditDetailString", "payload", "/client:AuditDetailString/client:auditDetail", auditDetailXml);

        addAuditTrailEntry("BPEL Variables set");
    }  
} 

} catch (Exception e) { 
    addAuditTrailEntry("Exception in getting Audit Trails and Details"); 
}

The sample payload to run above composite is:

    <element name="process">
        <complexType>
            <sequence>
                <element name="compositeName" type="string"/>
                                <element name="compositeId" type="string"/>
                                <element name="componentType" type="string"/>
                                <element name="componentName" type="string"/>
                                <element name="componentId" type="string"/>
            </sequence>
        </complexType>
    </element>

Sample Code

Please get the complete Jdeveloper Project as follows:

1. DummySOAApplication to retrieve initial payload of Mediator and BPEL components

2. The SOA Audit Trail Composite “SOAAuditTrails” that contains the logic to get initial payload of “Dummy Composite”

3. Sample Payload “SOA_audit_payload

 

 

Comments

  1. Pankaj Kumar says:

    Trying this in a one node cluster in SOA 11g , and getting following error on execution of :
    Composite composite = (Composite)locator.lookupComposite(compositeName);

    Error : Caller doesn’t have enough permission to call this method.

    Please let me know how to resolve.

  2. João Batista Ladchuk says:

    Does anyone have any information of how to get by 12c. I’ve tried all ways but it is not possible to return the data to the audit trail?

  3. Thanks for useful post. I am trying to access complete audit trail(with events element) and Payload of BPM instance using Facade API in BPM 12c environment. I am getting empty audit trail(with out events). Am i missing something? any help really appreciated. Please find the code and output below

    Code
    —–
    Component lookupComponent = (Component)locator.lookupComponent(“default/DehydAnalysisPrj!1.0/DehydProcessA”);
    ComponentInstanceFilter compInstFilter = new ComponentInstanceFilter();
    compInstFilter.setId(“110002”);
    List compInstances = lookupComponent.getInstances(compInstFilter);
    if (compInstances != null) {
    System.out.println(“====Audit Trail of Instance===”);
    for (ComponentInstance compInst : compInstances) {
    String compositeInstanceId = compInst.getCompositeInstanceId();
    String componentStatus = compInst.getStatus();
    System.out.println(“Composite Instance ID is “+compositeInstanceId);
    System.out.println(“Component Status is “+componentStatus);
    System.out.println(“Get Audit Trail”);
    String auditTrailXml = compInst.getAuditTrail();
    System.out.println(auditTrailXml);

    Output
    ———

    ====Audit Trail of Instance===
    Composite Instance ID is 110001
    Component Status is initiated
    Get Audit Trail

  4. Many of these API are not available in 12c version. Is there any follow up 12c blog, for this functionality ? Thanks.
    BTW, this was a great post.

Add Your Comment