Skip to Content

ody>

Adapter Module: AdapterModuleDCBypass


Use

Some adapters support specific message attributes, which contain additional information about messages. This information is not located in the payload of the message, but in additional message header fields called Dynamic Configuration. These attributes can be accessed in routing and mapping by using the attribute namespace and the technical name of the attribute.

Every time an adapter module is executed, message header is transferred from input to output message. However, when using Integrated Configuration Objects (ICOs), this header section is omitted on synchronous scenarios. The result is Dynamic Configuration section’s missing.

You use AdapterModuleDCBypass module to prevent Dynamic Configuration attributes to be deleted after adapter module is executed. It uses Supplemental Data, a Module Data area, to store temporarily all Dynamic Configuration properties before adapter module execution. Afterwards, AdapterModuleDCBypass retrieve all the properties stored in Supplemental Data and writes them back to Dynamic Configuration section.



Deployment

Enterprise Java Bean Project: AdapterModuleDCBypass-ejb

Enterprise Java Bean Application: AdapterModuleDCBypass-ear

Integration

The module can be used in any Sender or Receiver Adapter.

Activities

This section describes all the activities that have to be carried out in order to configure the module.

Entries in processing sequence

Insert the module before and after the adapter module as shown in the picture below.

Entries in the module configuration


The table below shows the possible parameters and values of the adapter module.

Parameter Type Possible Values Description
mode required DynamicConfiguration_to_ModuleData  | ModuleData_to_DynamicConfiguration

The mode parameter specifies the execution mode of the module.


When mode is [DynamicConfiguration_to_ModuleData] the module retrieves attributes from Dynamic Configuration and copies them to Module Data.


When mode is [ModuleData_to_DynamicConfiguration] the module retrieves attributes from Module Data and copies them to Dynamic Configuration.

Audit Log

The execution process can be followed in the audit log generated per message.



AdapterModuleDCBypassBean


package com.rav.integrations.modules;
import java.rmi.RemoteException;
import java.util.Enumeration;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.ejb.TimedObject;
import javax.ejb.Timer;
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.aii.af.service.auditlog.Audit;
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.auditlog.AuditLogStatus;
import java.sql.Timestamp;
/**
* @author rallue
*
*/
public class AdapterModuleDCBypassBean implements SessionBean, TimedObject {
    private static final long serialVersionUID = -1910739162843853923L;
    private static final String C_MODE_DC2MD = "DynamicConfiguration_to_ModuleData";
    private static final String C_MODE_MD2DC = "ModuleData_to_DynamicConfiguration";
    private static final String C_PARAM_MODE = "mode";
    private static final String C_KEY_SEPARATOR = "#";
    private static MessageKey amk;
    /*
    * (non-Javadoc)
    *
    * @see javax.ejb.SessionBean#ejbActivate()
    */
    @Override
    public void ejbActivate() throws EJBException, RemoteException {
        // TODO Auto-generated method stub
    }
    /*
    * (non-Javadoc)
    *
    * @see javax.ejb.SessionBean#ejbPassivate()
    */
    @Override
    public void ejbPassivate() throws EJBException, RemoteException {
        // TODO Auto-generated method stub
    }
    /*
    * (non-Javadoc)
    *
    * @see javax.ejb.SessionBean#ejbRemove()
    */
    @Override
    public void ejbRemove() throws EJBException, RemoteException {
        // TODO Auto-generated method stub
    }
    /*
    * (non-Javadoc)
    *
    * @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
    */
    @Override
    public void setSessionContext(SessionContext arg0) throws EJBException,
            RemoteException {
        // TODO Auto-generated method stub
    }
    /*
    * (non-Javadoc)
    *
    * @see javax.ejb.TimedObject#ejbTimeout(javax.ejb.Timer)
    */
    @Override
    public void ejbTimeout(Timer arg0) {
        // TODO Auto-generated method stub
    }
    public void ejbCreate() throws javax.ejb.CreateException {
    }
    public ModuleData process(ModuleContext moduleContext,
            ModuleData inputModuleData) throws ModuleException {
        String mode = "";
        Message msg;
        try {
            msg = (Message) inputModuleData.getPrincipalData();
            amk = new MessageKey(msg.getMessageId(), msg.getMessageDirection());
            addInfo("AdapterModuleDCBypassBean begin...");
            try {
                mode = moduleContext.getContextData(C_PARAM_MODE);
                if (mode != null && !mode.equals(C_MODE_DC2MD)
                        && !mode.equals(C_MODE_MD2DC)) {
                    mode = C_MODE_DC2MD;
                }
            } catch (Exception e) {
                mode = C_MODE_DC2MD;
            }
            if (mode.equals(C_MODE_DC2MD)) {
                addInfo("AdapterModuleDCBypassBean: mode - " + C_MODE_DC2MD);
                dcToMD(inputModuleData);
            } else if (mode.equals(C_MODE_MD2DC)) {
                addInfo("AdapterModuleDCBypassBean: mode - " + C_MODE_MD2DC);
                mdToDC(inputModuleData);
            }
        } catch (Exception e) {
            addInfo("AdapterModuleDCBypassBean: Exception found: "
                    + e.getMessage());
        }
        addInfo("AdapterModuleDCBypassBean end...");
        return inputModuleData;
    }
    @SuppressWarnings("unchecked")
    private void mdToDC(ModuleData inputModuleData) throws ModuleException {
        Message msg = null;
        MessagePropertyKey key;
        String propertyName = "";
        String propertyNamespace = "";
        String supplementalDataName;
        String supplementalData;
        String[] str;
        try {
            msg = (Message) inputModuleData.getPrincipalData();
            Enumeration<String> supplementalDataNamesList = inputModuleData
                    .getSupplementalDataNames();
            while (supplementalDataNamesList.hasMoreElements()) {
                try {
                    supplementalDataName = supplementalDataNamesList.nextElement();
                    if (supplementalDataName != null && supplementalDataName.contains(C_KEY_SEPARATOR)) {
                        supplementalData = (String) inputModuleData.getSupplementalData(supplementalDataName);
                        str = supplementalDataName.split(C_KEY_SEPARATOR);
                        if (str.length > 1) {
                            propertyName = str[0];
                            propertyNamespace = str[1];
                            key = new MessagePropertyKey(propertyName, propertyNamespace);
                            msg.setMessageProperty(key, supplementalData);
                            addInfo("mdToDC - propertyName = " + propertyName
                                    + " propertyNamespace = "
                                    + propertyNamespace
                                    + " supplementalData = " + supplementalData);
                        }
                    } else {
                        if (supplementalDataName == null) {
                            addInfo("mdToDC - Key ignored: supplementalDataName is null");
                        } else {
                            addInfo("mdToDC - Key ignored: supplementalDataName does not contain separator "
                                    + C_KEY_SEPARATOR
                                    + " : "
                                    + supplementalDataName);
                        }
                    }
                } catch (Exception e) {
                    addInfo("mdToDC - Key ignored: something went wrong while trying to read a key : "
                            + e.getMessage());
                }
            }
            inputModuleData.setPrincipalData(msg);
        } catch (Exception e) {
            addInfo("mdToDC - Exception Found: " + e.getMessage());
            throw new ModuleException(e.getMessage(), e);
        }
    }
    private void dcToMD(ModuleData inputModuleData) throws ModuleException {
        Message msg = null;
        String propertyName = "";
        String propertyNamespace = "";
        String supplementalDataName;
        String supplementalData;
        try {
            msg = (Message) inputModuleData.getPrincipalData();
            for (MessagePropertyKey key : msg.getMessagePropertyKeys()) {
                propertyName = key.getPropertyName();
                propertyNamespace = key.getPropertyNamespace();
                supplementalDataName = propertyName + C_KEY_SEPARATOR
                        + propertyNamespace;
                supplementalData = msg.getMessageProperty(key);
                inputModuleData.setSupplementalData(supplementalDataName,
                        supplementalData);
                addInfo("dcToMD - supplementalDataName = "
                        + supplementalDataName + " supplementalData = "
                        + supplementalData);
            }
        } catch (Exception e) {
            addInfo("dcToMD - Exception Found: " + e.getMessage());
            throw new ModuleException(e.getMessage(), e);
        }
    }
    private void addInfo(String msg) {
        try {
            msg = System.nanoTime() + " : " + msg;
            Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS, msg);
        } catch (Exception e) {
            Audit.addAuditLogEntry(amk, AuditLogStatus.ERROR,
                    "Error opening the file!");
        }
    }
    private void addWarning(String msg) {
        try {
            Audit.addAuditLogEntry(amk, AuditLogStatus.WARNING, msg);
        } catch (Exception e) {
            Audit.addAuditLogEntry(amk, AuditLogStatus.ERROR,
                    "Error opening the file!");
        }
    }
    private void addError(String msg) {
        try {
            Audit.addAuditLogEntry(amk, AuditLogStatus.ERROR, msg);
        } catch (Exception e) {
            Audit.addAuditLogEntry(amk, AuditLogStatus.ERROR,
                    "Error opening the file!");
        }
    }
}
To report this post you need to login first.

7 Comments

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

  1. Praveen Gujjeti

    Super and nice alternate solution. Great work !!  Roger

    BTW, I am not sure if this a defect in all SAP PI/PO versions ICO’s with synchronous mode not carrying dynamic configuration. If it is a defect in all current PI/PO versions, then SAP should fix this

    Best Regards,

    Praveen Gujjeti

    (0) 
    1. Roger Allue Post author

      Well I found it in a PI 7.31 system. I can’t remember the SP level, but I hope SAP fixes it if it’s a defect. While we wait for the final solution, it can be used as a workaround.

      Best Regards,

      Roger Allué Vall

      (0) 
  2. Adam Sosnowski

    This workaround does not work with HTTP_AAE (as of PO 7.50 SP03): The Supplemental Data gets deleted by the Adapter Module sap.com/com.sap.aii.adapter.http/HttpAdapterBean, too.

    (0) 

Leave a Reply