Skip to Content

XI/PI Message Payload from Java

Hello there again SDN!

It’s been a long time since my last blog, but… you know, not enough time. 😐

Anyway, I’m always thinking about beginning to write smarter and wider topics than techy stuff, but again it requires time. So, here I am again with a tech-pill for XI/PI guys.

I’ve been in touch with a SDN guy recently who asked me help via mail about how to get XI/PI message payload from Java (his requirement was to get from a JSP, to do some custom monitoring I guess). So I helped him out, and that’s a draft but working result.

You need a Java IDE (NWDS is ok), JDK and SAP Java Connector (JCo), plus a XI/PI box. The solutions leverages on a standard remotely enabled function module called SXMB_READ_MESSAGE_VERSION_RAW, which should be quite SPS independent.

Mind that if you’re running Java 5 you’ll need JCo 3.0.0, otherwise on Java 1.4.2_xx you’ll be using JCo 2.1.18. Everything can be download on the SAP Service Marketplace at this page. My version is using the old Java version, but shouldn’t make any real difference.

The Code

Here’s the code in a working simple stand-alone Java program. You should adapt it to fit your needs (actually I’d be doing a nicer Java class if had the time).

 

/*
 * Created on 15-set-2008
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.guarneri.jco.test;

/**
 * @author Talentlab
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */

import com.sap.mw.jco.IFunctionTemplate;
import com.sap.mw.jco.IRepository;
import com.sap.mw.jco.JCO;

public class PayloadExtractor {

    // The MySAP.com system we gonna be using
    static final String SID = "SID";

    // The repository we will be using
    IRepository repository;
    JCO.Field msgkeyField;

    public PayloadExtractor() {
        try {
            System.out.println("*** Creating the Pool... ***");
            JCO.addClientPool(SID, 10, "001", "user", "pwd", "EN", "host", "00");
            repository = JCO.createRepository("RecoverRepository", SID);
        } catch (JCO.Exception ex) {
            System.out.println("RecoverXI Caught an exception: \n" + ex);
        }
    }

    // Retrieves and prints information about the remote system
    public void getPayload() {
        // A messageID from your XI/PI
        String key = "48CD01EB3D27021BE1008000C0A8477D";
        final String pipelineID = "CENTRAL";

        byte[] msgkey = key.getBytes();
        try {
            IFunctionTemplate ftemplate = repository.getFunctionTemplate("SXMB_READ_MESSAGE_VERSION_RAW");
            if (ftemplate != null) {
                System.out.println("*** Creating client and function... ***");
                JCO.Function function = ftemplate.getFunction();
                JCO.Client client = JCO.getClient(SID);
                JCO.Structure struct = function.getImportParameterList().getStructure("MESSAGEKEY");
                struct.setValue(key, "MSGID");
                struct.setValue(pipelineID, "PID");
                // SELECTION must be like this!
                function.getImportParameterList().getField("SELECTION").setValue("2");
                // This is the msg version number, where 000 is the first (Inbound); the last can be caught from the function output (see below).
                // Setting this strongly depends on what you want to get: basically before or after the mapping...
                function.getImportParameterList().getField("VERSION_REQUEST").setValue("000");
                System.out.println("*** Calling... ***");
                client.execute(function);
                JCO.Table tb = function.getExportParameterList().getTable("MESSAGEPAYLOAD");
                if (tb.getNumRows() > 0) {
                    // There could be multiple payloads (even if usually it's only one)
                    do {
                        String plstr = new String(tb.getField("PAYLOAD").getByteArray());
                        System.out.println(
                            "*** Payload found *** " + tb.getField("NAME").getString() + " *** BEGIN ***");
                        System.out.println(
                            "Message Last Version: "
                                + function.getExportParameterList().getField("MAXVERSION").getString());
                        System.out.println(plstr);
                        System.out.println(
                            "*** Payload found *** " + tb.getField("NAME").getString() + " ***  END  ***");
                    } while (tb.nextRow());
                } else {
                    System.out.println("*** No payload found! ***");
                }
                // Release the client into the pool
                JCO.releaseClient(client);
            } else {
                System.out.println("Function SXMB_READ_MESSAGE_VERSION_RAW not found in backend system.");
            }
        } catch (Exception ex) {
            System.out.println("Caught an exception: \n" + ex);
        }
    }

    protected void cleanUp() {
        System.out.println("*** Cleaning... ***");
        JCO.removeClientPool(SID);
    }

    public static void main(String[] argv) {
        PayloadExtractor e = new PayloadExtractor();
        e.getPayload();
        e.cleanUp();
    }

}

Remarks

I know, the code is not that elegant. Forgive me.

I know, this is no great surprise. Maybe even not so useful.

There are a number of things I don’t know about this function, but only one thing is sure: it works, like this. Make your own experiments (maybe more quickly in trx SE37 via SAPGui) and discover new features. Come back here to this blog if you find something interesting.

8 Comments
You must be Logged on to comment or reply to a post.
    • Dear sir,

      I realize that function module is not present in SAP ECC 6.0 and above.Worst part is that there is no matching and alternate,atleast cant find myself.Any workaround you can suggest me.

    • Another doubt is the input taken by this FM.How externally in java i can know before hand that you are looking to retrieve payload of 'XXXXX'
      message id as you do not have information of messageid by now.Rather messages id should have been queried by date like SXI_MONI.
  • Dear sir,
    At first sight it looked an elegant workflow.
    What i got by message payload is actual xml content of the messages.Message payload should ideally reside on XI server.In my XI box i do not have this function module SXMB_READ_MESSAGE_VERSION_RAW.Yea but i have the same function module there on my retail dev ecc server.But ideally i would have been glad if i am able to retrieve payload from XI box.I wish to know if this function module was actually present on your XI box ?
    • Hi Aditya,
      Of course it used to exist on my XI box! 🙂

      It may depend on XI/PI version, though.

      If you have it on another machine, copy and paste FM signature plus code in a new custom remote enabled FM in your XI/PI box and call that one!
      It's may be really that simple.

      Cheers,
      Alexx

  • nice blog!

    I tried creating a java app on jco3 for a new tool. It utilizes the same FM for extracting payload. However (I'm not sure what's happening), I can't seem to get an output from the FM. I always get 0 result. I tried in SE37 and the same result.. 🙁

    Do you have a few advice to give as to how I can solve this?

    Thanks in advance

    Bryan