Skip to Content
Author's profile photo Abhishek Ranjan

Sync/Async bridge SOAP scenario correlation

We have a number of blogs and resources available for the Sync/Async as well as Async/Sync scenarios.


I will be explaining below a particular scenario where the response need to come from the async bridge in a separate call and that needs to be correlated to the sync request message.

We ended up developing a module which is used in the sender communication channel which reads the request PI Message Id from the payload and set the correlation ID of the Message Header.


Requirement

  1. Sender is SAP system with a Sync service while receiver is a third party with async service.
  2. SOAP communication used on both sides.
  3. The sync request need to be closed with a response from the 3rd party.
  4. The 3rd party would be sending an async response based on the request received from SAP.
  5. The response then needs to be tied to the request and sent back to SAP.


Solution

In order to tie the Async response from 3rd Party to the Request from SAP we would need to correlate them. This can be done by setting the correlation ID in the response message with the request Message Id.


Option 1 – Though ASMA

The Request Message Id is passed in the XI Message Header to the 3rd Party and the same is returned in the Response Header attributes and set as the Correlation Id. Use the RequestOnewayBean and the WaitResponseBean in the Receiver SOAP adapter.

This has been detailed in the blog below

http://scn.sap.com/blogs/henrique/2007/08/02/syncasync-scenarios-without-bpm

The blog details how to set the correlation ID using the Filename in the File Adapter.

Similarly we can use the same concept for SOAP adapter using any of the Variable Headers i.e. XHeaderName1.

Option 2 – Though a custom module


The Request Message Id is passed in the payload to the 3rd Party and the same in returned in the Response payload. A custom module is used to read the payload value and set it as the Correlation Id.


Step 1

In the Message Mapping read the Request Message Id by using a UDF and populate it in a particular payload field.

Used a UDF to get the message header parameter “MESSAGE_ID”. Code Snippet below.


UDF1 for extracting the Message ID

messageID = (String) transformParam.get(StreamTransformationConstants.MESSAGE_ID);

returnParam = messageID;


Step 2

The Message Id returned by the UDF did not have the ‘-’ so we put the same back in the Message Id and then populate the target payload field.

Used another UDF to format the message id with the ‘-’. Code Snippet below.


UDF2 for formatting the Message ID

String finalMessageId = “”;

if(messageId.length()>31)

finalMessageId = messageId.substring(0,8)+”-“+messageId.substring(8,12)+”-“+messageId.substring(12,16)+”-“+messageId.substring(16,20)+”-“+messageId.substring(20,32);

else

finalMessageId = messageId;

return finalMessageId;


Step 3

Use the RequestOnewayBean and the WaitResponseBean in the Receiver SOAP adapter as below in the screen shot.

Pic2.jpg


Step 4

Implement the module which reads the payload and sets the correlation ID.

This module to be used in the Sender SOAP adapter. Along with NotifyResponseBean.

Pic1.jpg


The code for the Custom Module


SetCorrelationBean Code

package XYZ;

import javax.ejb.CreateException;

import javax.ejb.SessionBean;

import javax.ejb.SessionContext;

import com.sap.aii.af.lib.mp.module.Module;

import com.sap.aii.af.lib.mp.module.ModuleContext;

import com.sap.aii.af.lib.mp.module.ModuleData;

import com.sap.aii.af.lib.mp.module.ModuleException;

import com.sap.engine.interfaces.messaging.api.Message;

import com.sap.engine.interfaces.messaging.api.MessageKey;

import com.sap.engine.interfaces.messaging.api.MessagePropertyKey;

import com.sap.engine.interfaces.messaging.api.PublicAPIAccessFactory;

import com.sap.engine.interfaces.messaging.api.XMLPayload;

import com.sap.engine.interfaces.messaging.api.auditlog.AuditAccess;

import com.sap.engine.interfaces.messaging.api.auditlog.AuditLogStatus;

public class SetCorrelationBean implements SessionBean, Module {

                public static final String VERSION_ID = “$Id://tc/aii/30_REL/src/_adapters/_sample/java/user/module/SetCorrelation.java#1 $”;

                  static final long serialVersionUID = 7435850550539048631L;

                  private SessionContext myContext;

                 

                  public void ejbRemove() {}

                 

                  public void ejbActivate() {}

                 

                  public void ejbPassivate() {}

                 

                  public void setSessionContext(SessionContext context)

                  {

                                  this.myContext = context;

                  }

                 

                  public void ejbCreate() throws CreateException {}

                 

                public ModuleData process(ModuleContext moduleContext, ModuleData inputModuleData)

                    throws ModuleException

                    {

                                                //String SIGNATURE = “process(ModuleContext moduleContext, ModuleData inputModuleData)”;

                                                AuditAccess audit = null;

                                                String MessageText = “”;

                                                String PayloadXML = “”;

                                                String xmlTag = “”;

                                                String correlationID = “”;

                                                String xmlTagValue = “”;

                                               

                                                Object obj = null;

                                                Message msg = null;

                                                MessageKey key = null;

                                                try

                                                {

                                                                                obj = inputModuleData.getPrincipalData();

                                                                                msg = (Message) obj;

                                                                                key = new MessageKey(msg.getMessageId(), msg.getMessageDirection());

                                                                                audit = PublicAPIAccessFactory.getPublicAPIAccess().getAuditAccess();

                                                                                audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS, “SetCorrelationBeanID: Entering into Module…”);

                                                                               

                                                                                //Extract message text

                                                                                XMLPayload xmlpayload = msg.getDocument();

                                                                                xmlpayload.getInputStream();

                                                                                MessageText = xmlpayload.getText();

                                                                               

                                                                                //Get the parameters to add the correlation id and other payload values.

                                                                                xmlTag = (String) moduleContext.getContextData(“xmlTag”);

                                                                                //Find the xmlTag value for xmlTag from payload

                                                                                xmlTagValue = FindXmlTagValue(MessageText,xmlTag);

                                                                               

                                                                                //set the correlation value to be set with the xml values extracted above

                                                                                if(xmlTagValue.length()>0)

                                                                                                correlationID = xmlTagValue;

                                                                               

                                                                                //Set the correlationID and incident guid

                                                                                msg.setCorrelationId(correlationID);

                                                                                audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS, “SetCorrelationID:Successfully set the value” + correlationID + “as CorrelationID.”);

                                                                               

                                                                                //Write the payload back

                                                                                PayloadXML = MessageText;

                                                                               

                                                                                //write the payload back after converting it into stream

                                                                                byte[] docContent = PayloadXML.getBytes();

                                                                                xmlpayload.setContent(docContent);

                                                                                msg.setDocument(xmlpayload);

                                                                                inputModuleData.setPrincipalData(msg);

                                                                                audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS, “SetCorrelationID:Leaving the Module!”);

                                                                                return inputModuleData;

                                                                               

                                                }

                                                                                catch (Exception e)

                                                                                {

                                                                                                ModuleException me = new ModuleException(e);

                                                                                                audit.addAuditLogEntry(key, AuditLogStatus.ERROR, “Exception:” + e.getMessage());

                                                                                                throw me;

                                                                                }

                                                                               

                    }

                                                public String FindXmlTagValue(String MsgText, String xmltag){

                                                                //Extract the xmlTag Values from payload

                                                                String payloadValue = “”;

                                                                String beginTag=”<“+xmltag+”>”;

                                                                String endTag=”</”+xmltag+”>”; 

                                                                int i,j,l; 

                                                                i=MsgText.indexOf(beginTag); 

                                                                l=beginTag.length(); 

                                                                j=MsgText.indexOf(endTag); 

                                                                if(i>=0 && i<j) 

                                                                { 

                                                                                payloadValue=MsgText.substring(i+l,j); 

                                                                }

                                                                return payloadValue;

                                                }

}


Assigned Tags

      7 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Hello Abhishek,

      Iam in a similar situation, Webservice (Sync) to File(Async) , (1) SOAP Sender to File Receiver - logging the mesage id. (2) File sender [RESP] to SOAP Receiver .. can you please guide me in this case how to maintain the module sequence , in your blog you mentioned SOAP Receiver I do not have a soap receiver in my case... i just added a dummy file receiver for response to call NotifyResponseBean

      Author's profile photo Former Member
      Former Member

      how u finally set correlation  i am also doing same scenario and getting error could not find correlationID

      Author's profile photo Former Member
      Former Member

      this is the module sequence in the sync response sender channel - this is to show the correlationID here is the file name... this blog actually shows a module program to set your desired correlationID instead of file name

      Author's profile photo Abhishek Ranjan
      Abhishek Ranjan
      Blog Post Author

      Hi Naina,

      Is your issue resolved? Do you still need any inputs?

       

       

      Author's profile photo Abhishek Ranjan
      Abhishek Ranjan
      Blog Post Author

      Hi Kishore,

      Is your issue resolved? Do you still need any help?

       

      Author's profile photo Former Member
      Former Member

      Hi Abhishek,

      No its not resolved, iam having issues to set the correlation ID between request and response?

      Author's profile photo Former Member
      Former Member

      Hi Abhishek

       

      Is there any UDF i need to write to fetch message ID as correlation ID.

      public String getMessageID(Container container) throws StreamTransformationException{
      String messageID = "";
      java.util.Map map = container.getTransformationParameters();
      messageID = (String) map.get( StreamTransformationConstants.MESSAGE_ID);
      return messageID;
      }

       

      this i saw somwhere....