Skip to Content

Hello friends,

I was involved in recent scenario:

Sender system  : Hi SAP PO, I am sending order request message.

SAP PO: Yes I will receive it with soap sender axis adapter

Sender system: Listen, but I need below message in acknowledgement saying that “you received my order” in the same session opened
by me:

  <?xml version=”1.0″ encoding=”UTF-8″?>

<cXML payloadID=”xxxx-XXXX-xxx” xml:lang=”en” timestamp=”2002-03-12T18:39:09-08:00″>

       <Response>

            <Status code=”200″ text=”OK”/>

       </Response>

</cXML>

and also you have to send my order request message to SAP ECC system,ok?

SAP PO: Oh ok. In that case I have to create response (acknowledgement) message for you since SAP ECC – the receiver will not send me
any message back. SAP ECC has inbound asynchronous proxy. The creation of response message for you will be achieved by custom handler – a basic java
class and I will add it to sender axis communication channel.

Sender system: Looks good, all d best 🙂 .

It is like:

  • Ariba is sending order request message to SAP PO via soap sender axis adapter with Qos “EO”
  • SAP PO will do mapping and send the message to SAP ECC
  • SAP PO need to generate/ create  and send order response
    message below in the same session – opened by Ariba while sending order request
    message.

<?xml version=”1.0″ encoding=”UTF-8″?>

<cXML payloadID=”xxxx-XXXX-xxx” xml:lang=”en” timestamp=”2002-03-12T18:39:09-08:00″>

       <Response>

            <Status code=”200″ text=”OK”/>

       </Response>

</cXML>

EndtoEndFlow.JPG

Intention behind this blog:

I must say that I found some blogs on custom handler, but I wanted to share one of the way to create response within SAP PO and send to sender
with QoS =”EO”. As ideally response message can be simulated by file adapter or receiver system, in our case receiver is SAP ECC – asynchronous one.

Also I could not find end to end process : writing Axis custom handler, packaging them and deploy process. So I thought to document my end to end scenario, which will be helpful to anyone who has to write custom handler.

Alternatives considered before adopting this approach:

RequestoneWaybean : Can not be used as we can not have
synchronous scenario with multiple receivers. As here we need to send one
response message to Ariba and we have to send order request message to CRM.

Adapter module: May be we could have achieved, but I was not
sure in which direction(sender/ receiver) I have to use it…

Final approach:

Finally I went to Axis custom handler approach, where using
custom handler we can intercept soap messages and modify them before it reaches
to messaging system. Custom handler is supported in soap with axis framework.

What is handler:

It is kind of simple java class extended from BasicHandler–where you will override “invoke” method to change soap request / responsemessage.

I have come across two types of handler:

Request handler : handler which is invoked by adapter
framework before it goes to SAP PO messaging system(in short you can write this
request handler if you want to modify soap request messages)

Response handler:  handler which is invoked after
messaging system sends response(in case you want to modify response message)

We will be using response handler.

Tools required:

Eclipse(to write code)

sdaMakerTool(refer link: http://scn.sap.com/docs/DOC-47124) for packaging SDA file for deployment

SoapUI(to test)

SAP PO development:

Please note that I will not go much detail in to SAP PO to SAP
ECC flow, as the intention of this blog is the showcase usage of custom handler
in creating sending response from SAP PO via soap axis framework and it can be
referred for anyone who wanted to edit soap messages.

ESR design:

Data type, Message type and service interface of type
outbound “Asynchronous” for order request outbound message.(Ariba to SAP PO
flow)

Data type, Message type and service interface of type
inbound “Asynchronous” for order request inbound  message (for SAP PO to SAP CRM  flow)

Note: Here you can create any data type, message type
considering any XML structure. I had used Order request cXML order request
structure. You can test this scenario end to end with any XML structure
provided you refer to custom handler code – which actually constructs message.

No need to create design objects – Data type,
message type, service interface for custom response message – as this is
generated by custom handler.

ID configuration:

ICO object :

One ICO object required from Ariba to SAP ECC.

Sender communication channel:

SenderCC.JPG

SenderCC.JPG

Note: highlighted is the complete class name along with package which is deployed using sdaMakertool.

Receiver adapter:

SOAP adapter with XI 3.0 protocol(to pass message to
receiver SAP ECC via server proxy – inbound async proxy)

No channel required to send custom response back to sender, as it is achieved by custom handler code using sender axis channel as above.

Eclipse – adding Axis jar files :

Download Axis jar files from Apache Download Mirrors  and extract them and add below jars to project build path. This will make sure eclipse recognize imports mentioned in the class and build the class file.

Eclipse_path.JPG

Finally source code for custom handler –

package mycomp.axis.handlers;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.TimeZone;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.message.SOAPBodyElement;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.axis.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;

public class ResponseHandler extends BasicHandler {
    public void invoke(MessageContext msgContext) throws AxisFault
    {
       /** Response handler to write custom Ariba response
             */
            try {
             String respTxt = createResponseText();
           
             /**
                 * Getting response soap message envelop and add
                 * response message to soap body
                 */
               
             SOAPMessage curMsg =  getSoapMessageFromString(respTxt);
             msgContext.setMessage(curMsg);
               
            } catch (Exception e) {
                throw AxisFault.makeFault(e);
            }
        }

private String createResponseText()

        {

         String payloadID = “1234”;

         // Get time stamp in GMT-800 format.

         String ts = getTimeStamp();

  

         String respText = “<?xml version=\”1.0\” encoding=\”UTF-8\”?>\r\n”+

        “<SOAP-ENV:Envelope xmlns:SOAP-ENV=\”http://schemas.xmlsoap.org/soap/envelope/\”><SOAP-ENV:Header/>\r\n” +

           “<SOAP-ENV:Body>”+

            “<cXML payloadID=\””+payloadID+”\” xml:lang=\”en\” timestamp=\””+ts+”\”>\r\n” +

           “<Response>\r\n” +

           “<Status code=\”200\” text=\”OK\”/>\r\n” +

           “</Response>\r\n” +

           “</cXML>\r\n” +

           “</SOAP-ENV:Body>\r\n” +

           “</SOAP-ENV:Envelope>”;

       

         return respText;

        }

private String getTimeStamp()

        {

         Date today = new Date();

         SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd’T’HH:mm:ssZ”);

            //root.setAttribute(“timestamp”,”2002-03-12T18:39:09-08:00″);

         sdf.setTimeZone(TimeZone.getTimeZone(“GMT-08:00”));

        // String[] zone = TimeZone.getAvailableIDs();

         /*

         for(int i =0;i<zone.length;i++)

         {

          System.out.println(zone[i]);

         }*/

         String timeStamp = sdf.format(today);

        // System.out.println(timeStamp);

         return timeStamp;

        }

}

That is it… and here is the result… 🙂 :

SoapUIResp.JPG

People who suppoted me :

Raghavendra Basavaraj, Piotr Podkowinski and my laptop.. 🙂 .

To report this post you need to login first.

14 Comments

You must be Logged on to comment or reply to a post.

  1. anurag singh

    Hi divyesh,

    while implementing your blog in sender soap axis adapter, we are getting following error

    message not processed: java.lang.ClassCastException: class com.sun.xml.messaging.saaj.soap.ver1_1.Message1_1Impl:library:saaj13@com.sap.engine.boot.loader.ResourceMultiParentClassLoader@1d69f46b@alive incompatible with class org.apache.axis.Message:library:com.sap.aii.af.axisproviderlib@com.sap.engine.boot.loader.ResourceMultiParentClassLoader@273e5037@alive

    it appears to have some issue with library:saaj13. Any guidance on how i can be corrected

    Just for some detail on out scenario, ours is a SOAP Axis to Idoc scenario. Where request is sent to Idoc through Sender soap axis adapter and using the handler we are trying to generate the response as Idoc is async

    (0) 
    1. divyesh vasani Post author

      Hi Anurag,

      Although not relevant but you can double check:

      Hope you have downloaded and added 1.4 version libraries to project build path in eclipse.

      I think check your below 2 lines in your code, it looks like you are referring MessageFactory class from different package:

      // here the variable factory should be of type “javax.xml.soap.MessageFactory”

      MessageFactory factory= new org.apache.axis.soap.MessageFactoryImpl();

      message = factory.createMessage(new MimeHeaders(), new ByteArrayInputStream(xml.getBytes(Charset.forName(“UTF-8”))));

      If still does not work, you can share complete code of handler and stack trace as well.

      –Divyesh

      (0) 
  2. Evgeniy Kolmakov

    Hi Divyesh!

    Thanks for your nice blog!

    I have similar scenario with one difference: my sender system doesn’t allow getting responses if outbound interface is asyncronous (it requires “procedure” call instead of “function” call). Can I make outbound interface synchronous and close it with this response message?

    (0) 
  3. Zhuohong Cheng

    Hi Divyesh,


    May I know how to deploy the custom Axis Handler? Do you mind provide mine me a step to step guide? I know how to deploy the provider libraries but don’t know how to include my handler to it. my handler is an enhance HTTP sender that i would like to replace the original one.


    Thanks!

    Vincent

    (0) 
    1. divyesh vasani Post author

      Hello Vincent,

      As I said in blog, you can use sdaMakerTool.jar file to create SDA file.

      Basically here you will include your JAR file(which is created out of your java class file) along with other axis jar files like axis.jar,commons-discovery-0.2.jar,commons-logging-1.0.4.jar,commons-net-1.0.0-dev.jar and wsdl4j-1.5.1.jar.

      Refer to this link http://scn.sap.com/docs/DOC-47124

      on the same.

      It is easy and convenient as it includes manifest file and packages SDA file as well.

      Hope this helps.

      Divyesh

      (0) 
      1. Zhuohong Cheng

        Hi Divyesh,

        I tried to deploy the Jar files from the Axis SDK with sample handler in note 1039369 com.sap.aii.adapter.axis.sample.rar and com.sap.aii.axis.sample.app.sda.

        I extract the Jar files from these two archives and attached them in the SDA Maker Tool with other library jars.

        /wp-content/uploads/2015/02/axisprovider_644364.png

        the new SDA deployed successfully and when I use in the adapter:

        /wp-content/uploads/2015/02/usehandler_644365.png

        it gave me “handler is not instantiated” error.

        and here is the provider.xml:

        <?xml version=”1.0″?>

        <provider-descriptor>

          <display-name>XPI Axis Provider Library</display-name>

          <component-name>com.sap.aii.af.axisproviderlib</component-name>

          <provider-name>sap.com</provider-name>

          <references>

            <reference type=”library” strength=”strong” provider-name=”sap.com”>com.sap.base.technology.facade</reference>

            <reference type=”library” strength=”strong” provider-name=”sap.com”>engine.j2ee14.facade</reference>

          </references>

          <jars>

           <jar-name>lib/addressing-1.0.jar</jar-name>

           <jar-name>lib/axis.jar</jar-name>

           <jar-name>lib/com.sap.aii.adapter.axis.sample.ejb.jar</jar-name>

           <jar-name>lib/com.sap.aii.adapter.axis.sample.jar</jar-name>

           <jar-name>lib/com.vces.axis.jar</jar-name>

           <jar-name>lib/commons-codec-1.4.jar</jar-name>

           <jar-name>lib/commons-discovery-0.2.jar</jar-name>

           <jar-name>lib/commons-httpclient-3.0.jar</jar-name>

           <jar-name>lib/commons-logging-1.0.4.jar</jar-name>

           <jar-name>lib/commons-net-1.0.0-dev.jar</jar-name>

           <jar-name>lib/opensaml-1.0.1.jar</jar-name>

           <jar-name>lib/wsdl4j-1.5.1.jar</jar-name>

           <jar-name>lib/wss4j-1.5.11.jar</jar-name>

           <jar-name>lib/xalan-2.7.1.jar</jar-name>

           <jar-name>lib/xercesImpl-2.9.1.jar</jar-name>

           <jar-name>lib/xmlsec-1.4.4.jar</jar-name>

          </jars>

        </provider-descriptor>

        which step i went wrong? I am trying to understand the steps to deploy custom handler and will deploy mine with correct steps.

        Thanks!

        Vincent

        (0) 
        1. divyesh vasani Post author

          Dear Vincent,

          Sorry I could not revert you earlier.

          But  if still not resolved, one hint I can think of – you have to restart PI system to get it.

          (0) 
  4. Ankit Srivastava

    Hello Divyesh,

    A very nice blog. Can you provide a little more insight on what values to enter into process sequence and module configuration for this custom handler.

    Thanks,

    Ankit

    (0) 
    1. divyesh vasani Post author

      Hello Ankit,

      thank you very much.

      I had  put screenshot of my communicaiton channel – configured with exact sequence.

      Basically if it is request handler – meaning you want to modify request message- then you have to add custom handler before -callSapAdapter standard module.

      If it is respponse handler- put it after callSapAdapter standard module.

      Hope this helps.

      (0) 

Leave a Reply