Setting Dynamic Configuration Attributes Using Custom Adapter Module in Advanced Adapter Engine of PI/PO
When facing the requirement that drives necessity of manipulating dynamic configuration attributes of processed message (for example, adapter specific message attributes) in SAP PI/PO, there are couple of approaches that are commonly utilized:
- Access dynamic configuration attributes from mapping, via custom mapping function (user defined function / function library in graphical mapping or dedicated logic in Java mapping program) and making use of SAP standard mapping API. This approach is used probably is vast majority of cases and has many examples of its application for various adapter types, described on SCN – for example, Dynamic and yet perfectly Static Benefits and Generate Dynamic Queue in PI Java Only.;
- Use SAP standard adapter modules shipped with Adapter Engine – such as DynamicConfigurationBean ( Adding DynamicConfigurationBean in the Module Processor – Adding Modules to the Module Processor – SAP Library). There are several SCN materials discussing and illustrating this approach – for example, Unknown use case of DynamicConfigurationBean: Store file name to JMS header without mapping and Copy value from Request message to Response message using DynamicConfigurationBean and dynamic header fields.
In this blog, I would like to share the alternative approach, which is based on usage of custom adapter module. Why would we need custom adapter module, which is relatively more complex and requires more efforts during development and support/maintenance, if we are already equipped with widely used approaches highlighted above? Depending on specific developed scenario and requirements, there can be several reasons for this:
- Technical restrictions of SAP standard adapter modules. Known and commonly used SAP standard adapter modules are limited to determining value of the dynamic configuration attribute based on message header and payload – if value determination requires more complex logic, it is commonly implemented in the mapping.
- Nature (precisely, time dependency) of set dynamic configuration attributes. In some cases, adapter specific message attribute value is only valid for a given period of time – good example here is authentication tokens acquired from identity provider and used when calling receiver system (commonly by means of injection of these tokens in header of the message constructed by receiver adapter). Tokens validity may vary from several minutes to several hours, but the core idea is based on expiration of earlier generated token and necessity of acquiring new token / refreshing outdated token if the message could not get delivered within token validity period. Let us now imagine following situation: required adapter specific message attributes are populated from mapping, and staging is enabled for steps before mapping and after mapping (such combination may be used to get the persisted staged version of the message after it passed mapping). Having this in mind, let’s assume the processed message failed during its execution in receiver communication channel. By default, retry mechanism of Adapter Engine will attempt to automatically reprocess message from its last staged version with successful status – which is, in our case, message version after mapping. What if retry failed several times, or retry interval was increased, or combination of both, and by time when the message was sent to the receiver system, value assigned to adapter specific message attribute, got expired? Receiver system will not accept such message and will likely reject it (at least if it is authentication related process) causing another error for this message processing lifecycle in PI/PO. It will require manual reprocessing of the message from the version before mapping so that adapter specific message attribute population logic can be re-executed and time dependent value can be refreshed properly.
- Transparency of executed message processing steps and segregation of adapter agnostic mapping and adapter specific functionalities. Ideally mapping shall implement communication technique and protocol agnostic logic – whereas adapter specific message attributes are clear indication of binding of the mapping to specific used adapter type. In many cases this is very minor logic in comparison to the whole mapping logic, but it may also become complicated and time consuming in some other scenarios (especially if determination of the value for the adapter specific message attribute contains call outs and look ups to external systems or advanced internal computation). Why shall mapping foot the bill for these operations? Coupling of such logic within single mapping may also have far-reaching implication faced during performance analysis of messages processing, especially when conducting analysis of aggregated figures: observation of consistently long-running mapping step will not clearly evidence if this is caused by pure mapping functionality or originates from adapter specific message attribute related logic.
With this in mind, let me illustrate how we can effectively manipulate dynamic configuration attributes using custom adapter module. The blog was inspired by reverse engineering of already mentioned adapter module DynamicConfigurationBean and introducing some degree of flexibility and extensibility on top of its core internals. The approach can be used to enhance module processing sequence of sender or receiver communication channel flows and targets similar use cases as those highlighted above.
The approach is based on accessing dynamic configuration attributes and enabling get/add/update/delete operations against attributes in question, using several standard classes of Adapter Framework. The whole high level logic can be logically split into following sections:
- Using message data passed to the invoked adapter module by runtime (Module Processor component), access internal representation of the processed XI message;
- Using one of internal message handler classes, retrieve dynamic configuration of the message;
- Perform necessary operations (get/put/remove) with dynamic configuration attribute(s).
Below are technical details describing most significant aspects of these steps.
Access internal representation of the processed XI message
Within the developed custom adapter module, it is firstly required to access representation of the processed XI message (XIMessage), followed by retrieving its internal representation – XMB message (Message): (hereinafter class names are referred using their canonical names in order to avoid confusion related to classes with identical names, but located in different packages – especially considering the fact that some of those classes are a part of SAP standard SPI and API contract for the developed adapter modules, whereas others are a part of Adapter Framework internal classes)
com.sap.aii.adapter.xi.ms.XIMessage xiMessage = (com.sap.aii.adapter.xi.ms.XIMessage) moduleData.getPrincipalData(); com.sap.aii.af.sdk.xi.mo.Message xmbMessage = (com.sap.aii.af.sdk.xi.mo.Message) xiMessage.getXMBMessage();
Retrieve dynamic configuration of the message
Using class XMBMessageOperator, that is a part of Adapter Framework and that provides rich capabilities in part of manipulation with various message components – header and its attributes, payload, etc. – using respective getter and setter methods, obtain collection of dynamic configuration attributes (DynamicConfiguration):
com.sap.aii.af.sdk.xi.mo.xmb.DynamicConfiguration dcAttributes = com.sap.aii.af.sdk.xi.mo.xmb.XMBMessageOperator.getDynamicConfiguration(xmbMessage, true);
Perform necessary operations (get/put/remove) with dynamic configuration attribute(s)
DynamicConfiguration is collection like object – which means, having it obtained, we can now get collection entries (which are individual dynamic configuration attributes), remove them or add required additional entries using corresponding get/put/remove methods.
Since this all is executed in context of the invoked adapter module, flexible custom logic that is needed to achieve desired requirement in part of dynamic configuration attributes, can be implemented.
Sample adapter module
The demonstrated adapter module implements logic for setting specified dynamic configuration attribute. In sake of simplification and in order to avoid distraction from the blog’s core topic, logic implemented for the dynamic configuration attribute value determination, is very simple (it uses the input value and assigns it to the attribute value), but obviously it can be adopted to specific requirements and replaced with more sophisticated and advanced one.
Layout of interfaces and classes implemented in the module, is provided below:
- AddDynamicConfigurationBean. EJB implementing the adapter module, acts as a decorator responsible for retrieval and basic validation of module parameters and invoking class implementing dynamic configuration attributes handling logic (hereinafter referred as dynamic configuration provider class) using corresponding factory class (DynamicConfigurationProviderFactory);
- Subpackage ‘util’. Contains utility classes and interfaces used by the adapter module and intended to be used by dynamic configuration provider classes. Among other things, contains:
- factory class DynamicConfigurationProviderFactory – used for getting access to dynamic configuration provider classes from adapter module,
- interface DynamicConfigurationProvider – describes contract between adapter module and invoked dynamic configuration provider class,
- and some other underlying classes like exception classes, etc.
- Subpackage ‘provider’. Contains dynamic configuration provider implementation classes. Each class located in this package, shall be isolated self-contained class implementing interface DynamicConfigurationProvider, and can implement whatever logic required to manipulate dynamic configuration attributes as per faced requirements. Simple names of classes from this package are going to be used in adapter module configuration. In the initial version of the adapter module, the package contains:
- class DynamicConfigurationProviderDefault – default implementation of dynamic configuration provider class, intended to be used when simple assignment of given value to a specified attribute is required. Shall not be removed from the package since factory class looks for default dynamic configuration provider class in case specific custom dynamic configuration provider class is not specified in adapter module configuration,
- class DynamicConfigurationProviderExample – example of custom implementation of dynamic configuration provider class. In current version of the adapter module, it makes call of the default dynamic configuration provider class and is used only for demonstration purposes.
As mentioned earlier, the adapter module uses several classes of Adapter Framework that are not a part of standard libraries set used during adapter module development – having this in mind, if adoption of adapter module itself (not dynamic configuration provider classes) is undertaken, following additional libraries will be required:
Adapter module configuration
Module name: Custom_AF_Modules/AddDynamicConfigurationBean.
Accepted and valid adapter module parameters are listed below:
Name of the class implementing dynamic configuration provider logic. The class is the looked up in subpackage ‘provider’ of the package of the adapter module.
If not provided, the default dynamic configuration provider class (DynamicConfigurationProviderDefault) is used.
Parameter(s), which value is(are) passed to dynamic configuration provider class as input parameter(s).
Note that parameter names shall be prefixed with ‘dc.’ – for example, adapter module parameter ‘dc.code’ will be passed to dynamic configuration provider class as parameter ‘code’ (with omitted prefix).
Recognizing possible necessity of providing sensitive parameter values (password like values), the adapter module can also accept parameter names prefixed with ‘pwd’ (SAP PI/PO standard functionality in adapter modules configuration user interface used to mask input adapter module parameter value in communication channel configuration screen). In this way, prefixes ‘pwd.dc.’ and ‘pwddc.’ (depending on your preferences, you can either delimit ‘pwd’ and ‘dc’ prefixes with full stop to make them more readable, or write them both in one word) are also valid, same principles of parameter name derivation as for those prefixed with ‘dc.’ apply – namely, mentioned prefixes will be omitted when passing parameters to dynamic configuration provider class.
Adapter module configuration can contain as many these parameters, as required by specific invoked dynamic configuration provider class. Besides parameter prefixes, parameter names and values are not validated by adapter module and are passed to dynamic configuration provider class as is. It is dynamic configuration provider class’s responsibility to handle and make use of them.
Let me take one of commonly faced requirements relevant for adapter specific message attributes, and see how the developed adapter module can cope with them. A sample scenario uses file receiver communication channel. The requirement is to set file name at runtime and overwrite the file name specified during configuration time (in communication channel configuration). In sake of simplification, new file name is a fixed value and is not dependent on message (header or payload) or any more advanced logic. This requirement can be fulfilled using either of techniques mentioned at the beginning of this blog.
Below is configuration of parameters of the file receiver communication channel. As seen from screenshots, specified file name is ‘default_file_out.txt’, as well as adapter specific message attributes support is enabled and file name attribute is selected in order to enable support of set adapter specific message attribute holding dynamically determined file name, in the file adapter:
In adapter module processing sequence, the developed adapter module is inserted and corresponding sample dynamic configuration provider class is specified together with accompanying parameters required for its execution (as written earlier, particular parameters are individual to every implementation of dynamic configuration provider). In adapter module configuration, the file name is to be set to ‘custom_file_out.txt’:
After the scenario is executed, we can evidence from the message processing log that the custom adapter module was invoked and the generated file had overwritten file name:
As written earlier, dynamic configuration provider class can implement literally any required logic and get/put/remove as many dynamic configuration attributes, as it is required (not limited to processing just one attribute at a time) – demonstration provided above is only to highlight main aspects of the approach in action and the adapter module usage.
Source code and deployable
Source code of the adapter module and corresponding accompanying development artifacts are available at
Compiled and built latest version of the adapter module, assembled into deployable EAR file, is available at
The adapter module has been compiled in compliance to JDK 1.6, and has been successfully tested in PO 7.31 and PO 7.4 systems.
When to use the described approach and when to employ more common alternatives mentioned at the beginning of the blog? As it can be seen, none of these approaches is ideal and every one has certain strengths and weaknesses, which shall be taken into consideration when choosing the most appropriate option for accessing dynamic configuration attributes. Introduced custom adapter module (or, generally speaking, the described approach) is no exception from this: it provides flexibility in building custom implementations and embedding them in communication channel processing logic, but payoff for this is increased complexity of the developed solution, causing extra development and maintenance efforts.