Based on a custom requirement to carry out performance analysis on a critical interface "on-demand", I was looking at options. Obviously going to the SXMB_MONI, opening each message to find out which payload was demanded for, then coming back with a message ID and using it in RWB performance monitoring was an option. However the number of messages we did for kept increasing. Searching on SCN lead me to a wonderful blog created by Alessandro Guarneri in 2008. It provided me a good insight. However the API's have changed and so has the way of querying & parsing data. Based on Alessandro's blog and SAP JCo documentation and examples, here is the latest way of going about it:
Download JCo from Service marketplace:
http://service.sap.com/connectors
SAP Java Connector (SAP JCo) -> Tools & Services -> Download SAP JCo Release 3.0
(I used 64bit x86 for my 64 bit Windows running 32 bit JRE and worked well for me)
Install JCo on your laptop
sapjco3.dll
neither into the {windows-dir}\system32
nor into the {windows-dir}\SysWOW64
directory. This will break the operability of other JCo versions that are already installed on the same system. Furthermore you would risk that the current installation also would not work anymore, if the sapjco3.dll
gets replaced in the respective Windows system directory in the future. {sapjco3-install-path}
to the PATH
environment variable.Finally, add
{sapjco3-install-path}\sapjco3.jar
to your CLASSPATH
environment variable.
Code
import java.util.Properties;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoStructure;
import com.sap.conn.jco.JCoTable;
import com.sap.conn.jco.ext.DestinationDataProvider;
public class PayloadExtractor {
static String DESTINATION_NAME1 = "ABAP_AS_WITHOUT_POOL";
//Set the connection parameters
static {
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "hostname");
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "sysnr");
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "clientnr");
connectProperties.setProperty(DestinationDataProvider.JCO_USER, "usernm");
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "pwd");
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "en");
}
/*
* Connects to the server and prints the connection parameter to the standard IO
*/
public static void connectToServer() throws JCoException {
JCoDestination destination = JCoDestinationManager.getDestination(DESTINATION_NAME1);
System.out.println("Attributes:");
System.out.println(destination.getAttributes());
System.out.println();
}
/*
* Gets the message payload
*/
public static void getPayload() {
//MessageID
String key = "0001ECC1B4AA4C75257AD9C410DB8E4";
final String pipelineID = "CENTRAL";
try {
JCoDestination destination = JCoDestinationManager.getDestination(DESTINATION_NAME1);
//Function used to the message payload
JCoFunction function = destination.getRepository().getFunction("SXMB_READ_MESSAGE_VERSION_RAW");
if (function != null) {
//Setting import parameters
JCoParameterList params = function.getImportParameterList();
params.setValue("SELECTION", "2");
JCoStructure struct = function.getImportParameterList().getStructure("MESSAGEKEY");
struct.setValue("MSGID", key);
struct.setValue("PID", pipelineID);
params.setValue("MESSAGEKEY", struct);
//Execute the program
function.execute(destination);
//Retriving the export parameters
JCoTable returnTable = function.getExportParameterList().getTable("MESSAGEPAYLOAD");
for (int i = 0; i < returnTable.getNumRows(); i++) {
returnTable.setRow(i);
System.out.println(convertHexToString(returnTable.getString("PAYLOAD")));
}
}
} catch (Exception ex) {
System.out.println("Caught an exception: \n" + ex);
}
}
/*
* The payload is returned as a Hexadecimal. Following function coverts it to String
*/
public static String convertHexToString(String hex) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hex.length() - 1; i += 2) {
String output = hex.substring(i, (i + 2));
int decimal = Integer.parseInt(output, 16);
sb.append((char) decimal);
}
return sb.toString();
}
public static void main(String[] args) throws JCoException {
connectToServer();
getPayload();
}
}
Credits to Alessandro Guarneri for his original blog - XI/PI Message Payload from Java
I have removed exception handling and other complexities from the code to keep it simple for the purpose of this blog.