Skip to Content

Acknowledgment request generated by adapters of Adapter Engine not possible – not any more!

Recently I started to wonder what is so special inside Adapter Engine or XI/PI message that adapters residing on Adapter Engine cannot request for acknowledgment message from target system. If application acknowledgment in case of third party systems is not possible and this true is fully understandable so why we cannot receive at least transport acknowledgment message from Adapter Engine.

According to SAP in case of sender adapters of Adapter Engine they don’t request for acknowledgment. Similar situation is with receiver adapters of Adapter Engine where sender system have to ask for acknowledgment, than receiver adapter of Adapter Engine will generate acknowledgment message. Sounds ok, but according to those rules only sender adapters not residing on Adapter Engine can ask receiver for acknowledgment message. So it means only Abap stack adapters: Proxy, Idoc, Http and WSRM are capable to do this. Let me show you how to generate this acknowledgment message with small development.

For more details about standard acknowledgment possibilities see this link:

http://help.sap.com/saphelp_nwpi711/helpdata/en/48/ce29693a8e5430e10000000a42189b/frameset.htm

Background

First of all let see what is the diference betwean XI Messages that ask for acknowledgment and that don’t ask for it. To compare those two messages I will send same idoc type two times. First idoc will request for acknowledgment message and second will not do this. Configuration is done in standard program IDX_NOALE on PI.

First message (requests acknowledgment)

requests acknowledgment

Second message( do not request acknowledgment)

Do not request acknowledgment

As we can see first message contains information about requested acknowledgment in ReliableMessaging header of XI Massage. Second message also contains this header, but it indicate that for this message sender system do not expect any acknowledgment.

Sender adapter request acknowledgment

Let suppose i have File to File message flow. Now in sender file communication channel I add additional adapter module. This is custom module developed to request acknowledgment. Receiver file communication channel contains only standard adapter module but I will remove receiver agreement to ensure that receiver communication channel wouldn’t be involved in message processing.

Acknowledgment message has been generated with error as I expected, due to no receiver couldn’t be found.

After adding receiver agreement

So, whole secret is in custom adapter module. Let me show you code of this mystery

private ModuleData process_sender(ModuleContext imc, ModuleData imd) throwsModuleException

      {

            XIMessage aXIMessage = (XIMessage) imd.getPrincipalData();

            amk = new AuditMessageKey(aXIMessage.getMessageId(),AuditDirection.OUTBOUND);

            Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS, “Entry_OUTBOUND”);

            try

            {

                  XMBMessage xmb_m = aXIMessage.getXMBMessage();

                  Message xmbMessage = (Message) xmb_m;

 

      XMBMessageOperator.setApplicationAckRequested(xmbMessage,false);

                  XMBMessageOperator.setApplicationErrorAckRequested(xmbMessage,false);

                  XMBMessageOperator.setSystemAckRequested(xmbMessage,true);

                  XMBMessageOperator.setSystemErrorAckRequested(xmbMessage,true);

 

                  aXIMessage.setXMBMessage((XMBMessage) xmbMessage);

                  imd.setPrincipalData(aXIMessage);

 

            }

            catch(Exception e)

            {

                  Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS, ” Error Outbound: ” + e.getMessage());

            }

 

             returnimd;

      }

All what is needed in case of custom adapter module for sender communication channel is to set that what kind of acknowledgment is requested.

Receiver adapter request acknowledgment

In adapter’s receiver communication channel of Adapter Engine situation is much more different that in above example. Let suppose that we have proxy to file scenario. Request of acknowledgment message should be set in ECC’s  program/class that send message to PI. But we are not in charge of ECC and once interface is working and send messages to PI usually no one what to change anything. Due to Proxy adapter resides on ABAP stack, so I need to request for acknowledgment in receiver file communication channel that is on Adapter Engine.

Unfortunately code used above do not work in receiver communication channel. We can set ReliableMessaging header like above what indicate that we request acknowledgment but it does not work. Why ? After long time of tracing, debugging etc. I discovered that first of all message is stored in MessageStore, than custom module is called and at the end standard SAP moduleis invoked. Inside standard module lot of operations are performed but the most important is sendAcks(IGUID msgGuid). Inside this method standard message event handler is initialized ( in this case our message has profile XI, so it is XIEventHandler class) and onDeliveryAck method is called. This method evaluates based on XIMessage ReliableMessaging header, if acknowledgment is requested or not. Because method sendAcks receive only message guid, message’s header are fetched from MessageStore.

The problem is that to our custom module we receive only copy or clone of original message that is kept in MessageStore. So even if I change message’s ReliableMessaging header, this change is not reflected to MessageStore, from where XIMessage is later fetched to be evaluated by EventHandler and decided if acknowledgment was requested or not. Solution of this problem is to change “original” message that is stored in MessageStore.

No Problem, let see code below how this can be achieved.

private ModuleData process_receiver(ModuleContext imc, ModuleData imd)

            throws ModuleException

      {

            try

            {

                  XIMessage aXIMessage = (XIMessage) imd.getPrincipalData();

                  amk = new AuditMessageKey(aXIMessage.getMessageId(),AuditDirection.INBOUND);

                  Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS, “Entry_INBOUND”);

 

                  XMBMessage xmb = aXIMessage.getXMBMessage();

 

                  Message xmbm = (Message) xmb;

 

                  MessageStore ms = MessageStore.getInstance();

                  QueueMessage qm = ms.getQueueMessage(aXIMessage.getMessageKey());

 

                  if(qm != null)         

      ((XIMessage)qm.getTransportableMessage()).setAckRequestType(AckRequestType.SYSTEM);

 

            }

            catch(Exception ex)

            {

                  Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS, ” Error Inbound: ” + ex.getMessage());                              

            }

            return imd;

      }

As you can see I receive direct access to MessageStore and change ReliableMessaging header. Let’s try it and send message to PI.

Message form sxi_monitor in PI.

 

Message RealiableMessaging header

As you can see message do not contains ReliableMessaging header but  for it acknowledgment has been requested.

Conclusion

This solution contains extending java stack of Message processing, but it is also possible to extend ABAP Pipeline and add ReliableMessaging header to Message. But whole PI aim to only one Java Stack it is more useful to request acknowledgment on java side. Example has been prepared on PI 7.0

To report this post you need to login first.

3 Comments

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

  1. Alejandro Pertierra

    Hi Maciej Jarecki ,

    this solution is exactly what i need, but my problem relates in the code version. As far as i can see the code is for PI 7.0 y i need the similar code for PI 7.1

    is it possible that you post the code for PI 7.1  and the libraries used?

    Best Regards

    (0) 

Leave a Reply