Reading Messages from PI System
This blog describes how to retrieve information about messages from a PI system. PI has several interfaces which can be used to retrieve PI messages and other data from the system.
To read messages from a PI System, we have different solutions for Java and ABAP. They are not released as stable APIs and we don’t give assurance that it will never change. However, the APIs are usually stable in a release (and available since NetWeaver 7.0) and can be used to retrieve the data. Depending if the messages are retrieved from Java (Adapter Engine) or ABAP (Integration Engine) stack, there are different technologies. A web service can be used for the Java stack and ABAP function modules for the ABAP stack.
Retrieving Messages from Java
We offer a web service to retrieve messages from Java stack. The web service offers similar functionality to what can be done in the RWB Message Monitoring tool:
- Select messages which match a filter. You can filter by message header attributes like Time, Sender Component, Receiver Component, etc.
- Resend or Cancel Messages
- Retrieve the payload of a Message
This can be done with the web service AdapterMessageMonitoringVi which is delivered with a standard PI installation and is available with all releases. In 7.10, please check note 1373289 for availability limitations. The web service can be investigated and tested with the Web Services Navigator tool of the WebAS Java.
Web service WSDL URL is available at:
The web service also offers three different bindings for basic Http authentication, SSL over Https and HTTPS with client certificate authentication.
The actual web service URL depends on which binding is to be used and can be one of the follows:
In most cases the basic binding can be used if no special security requirements must be met.
The web service offers a set of operations/methods for different purposes. Some interesting methods for message monitoring are:
- getMessageList: Get a list of message. Input is a search filter similar to the filter in RWB Message Monitoring and the result contains the Messages and their header data (without the message payload) and status
- getMessagesByKeys: Similar to getMessageList, but search can be done only by a list of message keys.
- getMessageBytesJavaLangStringBoolean: Retrieve the payload of a message.
- getMessageBytesJavaLangStringIntBoolean: Retrieve the payload of a message.
- getLogEntries: Read the Audit Log of a message (see note 1814549 for required SPs and patch levels).
The web service also contains other methods, e.g. cancelMessage and resendMessage that can be used for message manipulation, but are not required for monitoring purposes. In newer releases like 7.30 and 7.31 the web service AdapterMessageMonitoringVi even contains many more methods for advanced monitoring (e.g. can be used for User-Defined Message Search) but which are out of scope for this document.
The method getMessageList can be used to search for messages which match to a given filter. This is according to the search functionality in RWB Message Monitoring.
The method has two input parameters:
- filter: A structured data type to give the search filter
- maxMessages: Integer value to limit the number of search results. It should always be provided to protect against high memory consumptions and out-of-memory situation.
The input structure for parameter filter contains many attributes of PI messages which are used to search for specific messages.
Important filter fields are:
- archive: search in the Message Archive or in the Database. Use false to search in the Database
- direction: Sender or Receiver direction. Valid values are “INBOUND” or “OUTBOUND”
- fromTime: The start time for the date/time selection
- toTime: The end time for the date/time selection. Find messages which are processed between fromTIme and toTime.
- interface: The message interface name and namespace
- messageIDs: A message ID for searching for a specific message. If a message ID is given in this field, all other filter attributes are ignored. Must be in the format of a 36 character length guid like “5ba9192c-fa6c-11e0-ca61-00001001a6a3”
- onlyFaultyMessages: If set to true, then only messages which had an error in the processing are in the result. This doesn’t mean that the current message status is “Error”. It can be a “Successful” message which at some point had an error.
- protocol: The message protocol. Should be “XI”
- qualityOfService: The message Quality of Service. Valid values are “EO”, “BE” and “EOIO”
- receiverInterface: Receiver interface name and namespace
- receiverName: Receiver Component name
- receiverParty: Receiver Party name
- senderInterface: Message sender Interface name and namespace
- senderName: Sender Component name
- senderParty: Sender Party name
- status: The message status. Valid values are “success”, “toBeDelivered”, “waiting”, “holding”, “delivering”, “systemError”, “canceled”. Only one status is possible per web service call. It’s not possible to send a combination of 2 or more status at a time.
Unused filter fields can be left empty so that they are not considered during the search. An example for a valid filter which searches messages with error status in a certain time interval can look like in the following screenshot:
Only fromTime, toTime and status are provided here. All other filter attributes are left empty and thus ignored.
The result of method getMessageList contains a structure with all search results, and for each result the message header information. An important field in the result structure is messageKey, because this field contains the input value which is required as input for the other methods getMessagesByKeys, getMessageBytesJavaLangStringBoolean and getMessageBytesJavaLangStringIntBoolean.
The following picture shows a part of the result:
The result contains an array of AdapterFrameworkData with one entry for each message that matched the filter.
This method works similar to method getMessageList. It returns a list of messages and their header attributes, but without the message payload. The only difference between the two methods is that it has only a list of message keys as input parameters.
This message keys have to be in the following format:
(Please note the backslash “\” at the end. It’s important to add it!)
- guid: the message id
- direction: the message direction. Can be “INBOUND” or “OUTBOUND” (without quotation marks)
- node: the server node id
- QoS: the quality of service. Can be “EO”, “BE” or “EOIO” (without quotation marks)
- seqNr: the sequence number for EOIO messages
An example for a valid message key is like this:
An invalid message key would be:
(all 5 parameters needs to be filled in the message key)
Please note: Only the fields guid and direction are really of importance here. All other fields can have “random” values (but the values should stay in the same parameter type; e.g. server node has to be integer, QoS has to be one of “EO”, “BE”, “EOIO”, etc.)
Methods getMessageBytesJavaLangStringBoolean and getMessageBytesJavaLangStringIntBoolean
The two methods getMessageBytesJavaLangStringBoolean and getMessageBytesJavaLangStringIntBoolean can be used to retrieve the payload of a message. Both methods work very similar, only the second method has an additional parameter for the message version (method one always returns the latest message version).
The other input parameters are
- archive: search in the Message Archive or in the Database. Use false to search in the Database
- messageKey: The message key to identify the message. The message key format is described above under method getMessagesByKeys. The message key can be obtained from the result of method getMessageList from result field messageKey
- version: The number of the message version to read. Use -1 to read the newest version, or a number larger/equal 0 to read older versions. E.g. if there are 4 message versions existing, valid values are 0, 1, 2 and -1. Please note that 3 isn’t a valid value in this example, since -1 has to be used to read the newest message version.
The result of this method contains a byte array with the serialized payload of the PI message. It can be deserialized and afterwards processed. For example it can be (depending on the payload type) parsed as XML document to extract several elements of the XML. In the code this can look similar to this:
// call web service to get data
byte msgBytes = adapterMessageMonitoringWS. getMessageBytesJavaLangStringBoolean(…);
// parse result
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(new ByteArrayInputStream(msgBytes), new MySAXHandler());
This method can be used to retrieve the Audit Log entries of a PI message. It has 5 input parameters:
- maxResults: Maximum number of results. The results are sorted by time/date in descending order (newest come first)
- olderThan: Only return Audit Log entries that are older than this timestamp. Can be used together with parameter maxResults to browse through a long list of audit log entries without overloading the web service client. If this parameter is not provided than the result starts with the newest log entries.
The return value contains a list with the Audit Log entries for the message with the timestamp, severity, text and some other data.
Retrieving Messages from ABAP
There are two important function modules to read the messages from the ABAP stack:
- SXMB_GET_XI_MESSAGE: retrieve the payload of a PI message
Both function modules are remote enabled and can be called externally, e.g. via JCO from a Java application. The functionality of the function modules is similar to the Java web service methods.
Function module SXMB_GET_MESSAGE_LIST
The function module can be used to search for messages which match to a given filter. This is according to the search functionality in RWB Message Monitoring or SXMB_MONI.
Input and output parameters of the function module:
- IM_FILTER: Type SXI_MESSAGE_FILTER; A filter to search for message which fulfill certain criterias
- IM_MESSAGE_COUNT: Type INT4; The maximum number of results. It should always be provided to protect against high memory consumptions and out-of-memory situation.
The data type SXI_MESSAGE_FILTER for the filter has the following important fields:
- FROM_TIME: TIMESTAMPL; UTC Time Stamp in Long Form (YYYYMMDDhhmmssmmmuuun) The start time for the selection interval.
- TO_TIME: TIMESTAMPL; UTC Time Stamp in Long Form (YYYYMMDDhhmmssmmmuuun) The end time for the selection interval.
- OB_PARTY: SXI_PARTY; XI: Communication Party; Sender Party
- OB_PARTY_TYPE: SXI_PARTY_TYPE; XI Partner: Identification Schema
- OB_PARTY_AGENCY: SXI_PARTY_AGENCY; XI Partner: Agency
- OB_SYSTEM: AIT_SNDR; Sending System
- OB_NS: RM_OIFNS; Outbound/Sender Interface Namespace
- OB_NAME: RM_OIFNAME; Outbound/Sender Interface Name
- IB_PARTY: SXI_PARTY; XI: Communication Party; Receiver Party
- IB_PARTY_TYPE: SXI_PARTY_TYPE; XI Partner: Identification Schema
- IB_PARTY_AGENCY: SXI_PARTY_AGENCY; XI Partner: Agency
- IB_SYSTEM: AIT_RCVR; Receiving System
- IB_NS: RM_IIFNS; Inbound/Receiver Interface Namespace
- IB_NAME: RM_IIFNAME; Inbound/Receiver Interface Name
- MESSAGE_IDS: SXMSCGUID_T; Character Format Message GUID Table. A message ID for searching for a specific message. If a message ID is given in this field, all other filter attributes are ignored. Must be in the format of a 32 character length guid like “5ba9192cfa6c11e0ca6100001001a6a3”
- QUALITY_OF_SERVICE: SXMSQOS; Integration Engine: Quality of Service. Valid values are “BE”, “EO” and “EOIO”
- CLIENT: SYMANDT; Client ID of Current User
- STATUS_TYPE: SXI_STAT_TYPE; XI: Type of a Status. A number for a status groups. Status groups pool together single message status values of the Integration Engine into groups with a semantic equal meaning. Valid numbers are:
05 Application Error
06 System Error
19 Manually Modified
21 Canceled with Errors
30 Waiting for Confirmation
50 Log Version
- STATUS: SXMSPMSTAT; Integration Engine: Message Status. Instead of a status group (with parameter STATUS_TYPE) now a single status can be given for the message search. For a list of all available status, please see contents of table SXMSMSTAT via transaction SE16.
The function module returns the search result in output parameter EX_MESSAGE_DATA_LIST. This structure contains a list of results of type SXI_MESSAGE_DATA. It contains the header information for all found PI messages.
Function module SXMB_GET_XI_MESSAGE
This function module can be called with the message ID (taken from the result of SXMB_GET_MESSAGE_LIST) and it returns the payload of the message. The result can be deserialized and further processed (e.g. parsed as XML document).
Input and output parameters of the function module:
- IM_MSGKEY: SXMSMKEY; XI: Message-Id as returned in the result of SXMB_GET_MESSAGE_LIST
- IM_ARCHIVE: SXMSFLAG; 1=read from archive, 0 = read from database; should be 0 to read from the database.
- IM_VERSION: SXMSLSQNBR; message version number; leave empty to get the latest version
- EX_MSG_BYTES: XSTRING; the bytes of the message
Nice Blog... Thanks for sharing......
But, what is the value addition? How different is it in providing the data from the one we see in RWB? I mean, do we get any extra data about the messages using this method?
It provides an alternative to RWB and the PIMON tools. Customers can use it to implement their own monitoring tools instead of using the standard PI tools.
Although the blog is already a few years old, it helped me a lot in my daily support work.
A separate monitoring tool was developed with the help of the web service and in my opinion this tool has an unbeatable advantage over normal monitoring via RWB:
Assuming you have to download a large number (10, 100, 1000) of messages with errors from the PI/PO system, then this work is very annoying using Message Monitoring (RWB).
However, if you use the options of the web service correctly, 10, 100 or even more messages can be downloaded with just a few clicks of the mouse.
Thank you for writing this wonderful blog.
this servlet was once not recommended for use in production:
1486734 - Problems Using AdapterMessageMonitoringVi
The AdapterMessageMonitoring service is not intended for use by external applications, as it might slow down overall message processing in the Adapter Engine, and cause memory consumption issues with large data sets. Therefore, it is not publicly documented and SAP does not recommend its use in production environment.
Do you have any information if this is still valid?
You're right. The note still mentions this. On the other hand, the Solution Manager also uses this web service to read data from PI systems.
We have to update the note and make the web service officially public available, maybe with some information about safety precaution measures to avoid harming the system while using it. For example, it should not be invoked several times per second and the input parameters should always provide a limit for the number of results.
Good blog .. !!
Is there a web service that provides information on the performance of the machine? as ==> SAP Netweaver Administrator ==> Availability and Performance ==> System Overview
It would be ideal to agree to both review the statistics..
Thanks for you help,
Thanks for the information.
I tried getMessageBytesJavaLangStringBoolean method for fetching the payloads but it giving me response in different format of usual.
Could you please explain me how to fetch the exact request payload using these methods.
Can we use getMessageList: method or call it externally through webservice without logging into SAP so that user can get from Time & toTime for number of interfaces ,say 5-600. Is there any way to get such report generated with these 2 parameters & interface names every regular intervals of 15-30 min and schedule it some email id.
The sender interface filter criteria doesnot work, only the interface name and namespace work, which have the receiver interface and namespace values. Especially, for ICO scenarios, if we need before mapping payloads of the messages; this filter criteria doesnt help.
Is it possible to fetch PI Message Monitoring logs based on the message ID.
Is there a way we can achieve this ?
I am facing an issue in the getMessageList response.
In the response both receiverInterface name and senderInterface name are coming as same name of interface name. This is wrong. attached the response below. (I have modified the interface name to ABC and receiverName as RECEIVER_NAME and senderName as SENDER_NAME).
In reality, sender and receiver interface names are different, but the response of the service is giving different.
Any idea? Is this a bug?
Hi Thanks for sharing.
This could be used when a negative situation (no files coming thru AS2 for example) that requires monitoring via alert is received?.