SOA Suite 11g – introducing Mediator Java Callouts for debug, audit and …

The Mediator component in SOA Suite 11g has a the option to specify a Java Callout, one for every WSDL operation. The Java Callout refers to a Java Class, either on the SOA Suite’s classpath or deployed as part of the SOA Composite application. This class should implement interface oracle.tip.mediator.common.api.IJavaCallout and a convenient way of doing so is by extending AbstractJavaCalloutImpl in package oracle.tip.mediator.common.api.

The Java Callout is invoked by the Mediator on a number of times, prior to and after performing the Routing Rule and each of the cases in it. The Java Callout class can implement a number of methods, one for each specific event or stage in the Mediator process. These methods get access to the input message as well as the transformation result. That means that the callout class can inspect, validate, log, audit and even manipulate these messages, their payloads, headers and properties. Interestingly enough, the methods are not static what I thought might be the case. The first one to be called is an initialize() that has you initialize the callout class instance to prepare the object for further callout processing. This means that all stages in a single Mediation action are processed by the same callout object. This allows you to compare for example the pre and post transformation values.

The methods that the callout interface specifies are: initialize, preRouting (before any routing rule cases are processed), preRoutingRule (before one specific routing rule is processed), preCallbackRouting (This method is called before Mediator finishes executing callback handling. You can customize this method to perform callback auditing and custom fault tracking.) , postCallbackRouting, postRoutingRule, postRouting.

This article shows a simple example of creating a SOA Composite Application – the simplest one you can create I believe using the new 11g feature of Echo – with use of the Java Callout class.

 

The steps to go through are fairly straightforward:

1. Create a new Application in JDeveloper of template SOA; select the option Composite with Mediator. I have called the Application and the Project MediatorCallout.

2. In the Create Mediator dialog, select the option Synchronous interface.

SOA Suite 11g - introducing Mediator Java Callouts for debug, audit and ... mediatorCallback1

This creates a Mediator with a WSDL and XSD that specifies an input message consisting of a single string and and response message with that same content.

3. Create a new static routing rule – of type Echo

SOA Suite 11g - introducing Mediator Java Callouts for debug, audit and ... mediatorCallback2

This is a new 11g feature that creates a simple short cut: the request is received, validated if so desired, transformed and returned to the invoker. No reference needs to be involved. This is what makes this the simples SOA Composite application – even simpler than the previous champion, the synchronous hello world BPEL process.

4. Create the transformation between request and response – by clicking on the transformation or mapping icon.

SOA Suite 11g - introducing Mediator Java Callouts for debug, audit and ... mediatorCallback3

Have a new mapper file created. Press the OK button to go to the mapper editor and define the mapping.

5. Complete the mapping

Connect the input element in the source/input/.request (left side) to the input element under the singleString element on the right side (target/response).

SOA Suite 11g - introducing Mediator Java Callouts for debug, audit and ... mediatorCallback4

At this point, the simplest SOA Composite application in the world is done. You can deploy it and invoke it. You send a string to it and receive the exact same string in return. By all means, try it out. But of course we are only just getting to the beef of this article.

6. Create a new Java Class in your project, under SCA-INF/src. Mine is called MediatorCalloutProcessor. This class should extend the class AbstractJavaCalloutImpl, that provides default (no-op) implementations for all methods defined in the interface oracle.tip.mediator.common.api.IJavaCallout.

package nl.amis.soasuite11g;

import oracle.tip.mediator.common.api.AbstractJavaCalloutImpl;

public class MediatorCalloutProcessor extends AbstractJavaCalloutImpl{


}

Now it is time to flesh out this class and have it actually do something – like intercepting the response message the Mediator has prepared for returning and inspecting & logging it.

Override the postRouting method. This method is invoked when the response message has been prepared.

  @Override
  public boolean postRouting(CalloutMediatorMessage calloutMediatorMessage,
                             CalloutMediatorMessage calloutMediatorMessage2,
                             Throwable throwable) throws MediatorCalloutException {
    System.out.println("Mediator has invoked Java Callout; executing postRouting");
    boolean returnValue =
      super.postRouting(calloutMediatorMessage, calloutMediatorMessage2,
                        throwable);
    String sPayload = "null";
    for (Iterator msgIt = calloutMediatorMessage2.getPayload().entrySet().iterator();msgIt.hasNext(); ) {
      Map.Entry msgEntry = (Map.Entry)msgIt.next();
      Object msgKey = msgEntry.getKey();
      if (msgKey.equals("reply")) {
          Object msgValue = msgEntry.getValue();
          sPayload = XmlUtils.convertDomNodeToString((Node)msgValue);
          System.out.println("Mediator sends reply: " + sPayload);
      }
    } //for
    return returnValue;
  }

Here we print two messages to the output (the command window in which the soa_server1  is running). The first message is just an indication that the Java Callout is invoked. The second one is more interesting: it shows the content of the Response Message that is about to be returned to the invoker.

The code loops over the documents in the payload of the CalloutMediatorMessage. When it finds the only that is associated with the key reply  we have found the response message, that we can then write to the output.

7. Configure the Mediator to invoke the Java Callout

SOA Suite 11g - introducing Mediator Java Callouts for debug, audit and ... mediatorCallback5

8. Deploy the SOA Composite application to the SOA Suite

9. Invoke the application from the FMW Control in Enterprise Manager; provide some input and verify that the input is echoed in the response message.

SOA Suite 11g - introducing Mediator Java Callouts for debug, audit and ... mediatorCallback6

Then inspect the output in the soa_server1 command window – to see whether the call out has taken place:

SOA Suite 11g - introducing Mediator Java Callouts for debug, audit and ... mediatorCallback7

Manipulating the response in the Java Callout class

A Java Callout class is potentially even more useful if it not just reads the messages, but manipulates them as well. As a very simple example, we will replace the response message with some XML document of our own design. One by the way that does not comply with the XSD definition for the request message – not something you should do in real life of course.

The code in the Java Callout class is slightly extended:

  @Override
  public boolean postRouting(CalloutMediatorMessage calloutMediatorMessage,
                             CalloutMediatorMessage calloutMediatorMessage2,
                             Throwable throwable) throws MediatorCalloutException {
    System.out.println("postRouting");
    boolean returnValue =
      super.postRouting(calloutMediatorMessage, calloutMediatorMessage2,
                        throwable);
    String sPayload = "null";
    for (Iterator msgIt = calloutMediatorMessage2.getPayload().entrySet().iterator();msgIt.hasNext(); ) {
      Map.Entry msgEntry = (Map.Entry)msgIt.next();
      Object msgKey = msgEntry.getKey();
      if (msgKey.equals("reply")) {
          Object msgValue = msgEntry.getValue();
          sPayload = XmlUtils.convertDomNodeToString((Node)msgValue);


        try {
          XMLDocument changedoc;
          changedoc = XmlUtils.getXmlDocument(sPayload);
          XMLNode input =
            (XMLNode)changedoc.selectSingleNode("//inp1:input", new LocalNamespaceResolver());
          System.out.println("the value of the input element = " + input.getTextContent());

          XMLDocument doc = prepareReturnMessage(input.getTextContent());

          String mykey = "reply";
          calloutMediatorMessage2.addPayload(mykey, doc.getDocumentElement());
        } catch (Exception f) {
          System.out.println(f);
        }

      }
    } //for
    return returnValue;
  }

And uses a helper method and private class to construct the response document:

  private XMLDocument prepareReturnMessage(String input) throws ParserConfigurationException {
    JXDocumentBuilderFactory factory =
      (JXDocumentBuilderFactory)JXDocumentBuilderFactory.newInstance();
    JXDocumentBuilder documentBuilder =
      (JXDocumentBuilder)factory.newDocumentBuilder();
    XMLDocument doc = (XMLDocument)documentBuilder.newDocument();
    doc.setVersion("1.0");
    doc.setEncoding("UTF-8");
    XMLElement hospitalElement = (XMLElement)(doc.createElement("hospital"));
    doc.appendChild(hospitalElement);
    XMLElement surgeonElement =
      (XMLElement)(doc.createElementNS("http://specialDoctorNamespace",
                                       "doc:surgeon"));
    hospitalElement.appendChild(surgeonElement);
    XMLText title =
      (XMLText)doc.createTextNode("Input After Manipulation " + input.toLowerCase().replace('e','x').replace('a','x'));
    surgeonElement.appendChild(title);
    return doc;
  }

  class LocalNamespaceResolver implements NSResolver {

    public String resolveNamespacePrefix(String prefix) {
      if ("inp1".equalsIgnoreCase(prefix)) {
        return "http://xmlns.oracle.com/singleString";
      }
      return null;
    }
  }


Note: you need to add the library Oracle XML Parser v2 to the project, in order to use the XMLDocument, XMLNode, XMLElement and XMLText classes.

When we deploy and run the SOA Application, regardless of our input, the response message looks something like:

SOA Suite 11g - introducing Mediator Java Callouts for debug, audit and ... mediatorCallback8

The output in the console window displays:

SOA Suite 11g - introducing Mediator Java Callouts for debug, audit and ... mediatorCallback9

Resources

Download JDeveloper 11g Application: MediatorCallout.zip.

10 Comments

  1. Tarun November 25, 2011
  2. Lucas Jellema November 13, 2011
  3. Lucas Jellema November 13, 2011
  4. Lucas Jellema November 13, 2011
  5. abhay November 7, 2011
  6. sumit October 31, 2011
  7. Praveen October 13, 2011
  8. C Soneson September 20, 2011
  9. Pierluigi Vernetto December 29, 2010
  10. Pierluigi Vernetto December 29, 2010