Skip to Content

1/20/2015: Updated with an example multi-map Payload

Multi-mapping dynamic configuration has been a frequent requirement and there are many open questions in SAP PI space, since multi-mapping doesn’t support dynamic configuration i.e., a separate dynamic configuration for each child message. Some time back I wrote a blog Multi-mapping: Assigning ASMA’s for Child Messages using Custom Adapter Module and FM but unfortunately that solution can’t be used for PI/PO single java stack systems

In this blog, I would like to share my new solution using a simple generic custom adapter module. The module can be used for any J2EE technical adapter by just configuring it in the respective communication channel. The module is applicable for all pi versions except few changes to import statements and few methods due to changes in module API. Highlighted the required changes as a comment in the attached module source code


Steps



  • Enhance each target message structure i.e., data type/external definition to have custom dynamic configuration header which will reflect in multi-mapping program as shown in the below snap shot. We enhance target structure mainly due to two reasons i. to utilize in the custom module to set dynamic headers for each child message ii. to easily remove the enhanced structure via module configuration and of course after step i

TargetStructure.png

  • Now you can map required dynamic header values (DC technical name, DC namespace and it’s value) either from source structure (or) via some lookup (or) some complex calculation using UDF based on your requirement. Please note that, DCRecord node occurrence is unbounded in nature and hence you can duplicate this structure how many ever times you want to utilize it for other DC technical attributes
  • The attached custom module expects two xpath parameters as input,
    1. DCXPATH – to evaluate dynamic headers from the child payload e.g., for the above defined structure it will be /MT_Receiver/DCHeader/DCRecord
    2. DCXPATHDEL – to delete the enhanced structure which is obviously not required by target system e.g., for the above defined structure it will be /MT_Receiver/DCHeader
  •     Deploy the custom module and use it in the required channel with the above mentioned parameters


Transformed Example Multi-Map Payload from Mapping:-


<?xml version="1.0" encoding="UTF-8"?>
<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
<ns0:Message1>
  <ns1:MT_Receiver xmlns:ns1="http://pg.com/multimap">
  <!-- ENHANCED DCHeader STRUCTURE for Dynamic Configuration -->
  <DCHeader>
  <DCRecord>
    <DCValue DCNameSpace="http://sap.com/xi/XI/System/File" DCTechnicalName="FileName">Data1.xml</DCValue>
  </DCRecord>
  <DCRecord>
    <DCValue DCNameSpace="http://sap.com/xi/XI/System/File" DCTechnicalName="Directory">./PI_OUT/Files/</DCValue>
  </DCRecord>
  </DCHeader>
  <!-- ACTUAL TARGET STRUCTURE -->
  <Name>Praveen1</Name>
  <EmpID>1234</EmpID>
  <Project>ABC</Project>
  </ns1:MT_Receiver>
  <ns1:MT_Receiver xmlns:ns1="http://pg.com/multimap">
  <!-- ENHANCED DCHeader STRUCTURE for Dynamic Configuration -->
  <DCHeader>
  <DCRecord>
    <DCValue DCNameSpace="http://sap.com/xi/XI/System/File" DCTechnicalName="FileName">Data2.xml</DCValue>
  </DCRecord>
  <DCRecord>
    <DCValue DCNameSpace="http://sap.com/xi/XI/System/File" DCTechnicalName="Directory">./PI_OUT/Files/</DCValue>
  </DCRecord>
  </DCHeader>
  <!-- ACTUAL TARGET STRUCTURE -->
  <Name>Praveen2</Name>
  <EmpID>4567</EmpID>
  <Project>XYZ</Project>
  </ns1:MT_Receiver>
</ns0:Message1>
</ns0:Messages>

That’s all. Hope this new solution is simple, efficient and can be useful for your projects. Please share your feedback to improve the code. Thanks..



To report this post you need to login first.

6 Comments

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

  1. Rafael Vieira

    Hello Praveen Gujjeti – thanks for this great material.

    I’m trying to understand how this would work in practical terms.

    Once we enhanced the target structure with DC Header (after having the custom module deployed) and DC XPath/Del parameters maintained in module configuration, what else is required to see the results?

    e.g: my requirement is to set file name dynamically with multi mapping (http://scn.sap.com/message/16901370#16901370).

    Would you have any practical example?

    Thanks in advance!

    (0) 
    1. Rafael Vieira

      Hello Praveen Gujjeti

      I tried to deploy the EAR file in NWDS but it returned a warning:

         S U M M A R Y

      ~~~~~~~~~~~~~~~~~~~

      Successfully deployed:      0

      Deployed with warnings:      1

      Failed deployments:      0

      ~~~~~~~~~~~~~~~~~~~

      1. File:C:\Users\rafael.silva\Downloads\EAR\PckgDCMultiMap_EAR.ear\DCMultiMap_EAR.ear

        Name:DCMultiMap_EAR

        Vendor:sap.com

        Location:localhost

        Version:2014.03.05.21.55.53

        Deploy status:Warning

        Version:NEW

        Description:

        1. Warning occurred on server 1199350 during deploy of sap.com/DCMultiMap_EAR : EJB Model Builder: ASJ.ejb.004096 The session bean class “com.dc.multimap.DCMultiMapBean” cannot be found in the search path. (Location:META-INF/ejb-jar.xml)[message resource bundle missing], file: DCMultiMap_EJB.jar#DCMultiMap_EJB.jar, severity: warning

      Warning occurred on server 1199350 during deploy of sap.com/DCMultiMap_EAR : EJB Model Builder: Bean class com.dc.multimap.DCMultiMapBean is not available in the ejb module archive file.[message resource bundle missing], file: DCMultiMap_EJB.jar#DCMultiMap_EJB.jar, severity: warning

      CSN component of deployment item is not available

        2. Exception has been returned while the [sap.com/DCMultiMap_EAR] was starting. Warning/Exception :[

      ][ASJ.dpl_ds.006153 Error occurred while starting application [sap.com/DCMultiMap_EAR]: It is not started successfully on server nodes [1199350]. In order to bring the server in consistent state stop operation will be performed.

      Error occurred on server 1199350 during startApp of sap.com/DCMultiMap_EAR : com.sap.engine.services.deploy.container.DeploymentException: Cannot load bean class com.dc.multimap.DCMultiMapBean for component sap.com/DCMultiMap_EAR*xml|DCMultiMap_EJB.jar*xml|DCMultiMap

        at com.sap.engine.services.ejb3.container.ContainerInterfaceImpl$Actions.perform(ContainerInterfaceImpl.java:1139)

        at com.sap.engine.services.ejb3.container.ContainerInterfaceImpl.prepareStart(ContainerInterfaceImpl.java:575)

        at com.sap.engine.services.deploy.server.utils.container.ContainerWrapper.prepareStart(ContainerWrapper.java:509)

        at com.sap.engine.services.deploy.server.application.StartTransaction.prepareCommon(StartTransaction.java:403)

        at com.sap.engine.services.deploy.server.application.StartTransaction.prepare(StartTransaction.java:324)

        at com.sap.engine.services.deploy.server.application.ApplicationTransaction.makeAllPhasesOnOneServer(ApplicationTransaction.java:430)

        at com.sap.engine.services.deploy.server.application.ApplicationTransaction.makeAllPhases(ApplicationTransaction.java:473)

        at com.sap.engine.services.deploy.server.application.ParallelAdapter.makeAllPhasesSequentially(ParallelAdapter.java:324)

        at com.sap.engine.services.deploy.server.application.StartTransaction.makeAllPhases(StartTransaction.java:693)

        at com.sap.engine.services.deploy.server.DeployServiceImpl.makeGlobalTransaction(DeployServiceImpl.java:1985)

        at com.sap.engine.services.deploy.server.DeployServiceImpl.startApplicationAndWait(DeployServiceImpl.java:2635)

        at com.sap.engine.services.deploy.server.DeployServiceImpl.startApplicationOnInstanceWait(DeployServiceImpl.java:2887)

        at com.sap.engine.services.deploy.server.DeployServiceImpl.startApplicationOnInstanceAndWaitAuth(DeployServiceImpl.java:3036)

        at com.sap.engine.services.deploy.server.DeployServiceImpl.startApplicationAndWait(DeployServiceImpl.java:2588)

        at com.sap.engine.services.dc.lcm.impl.J2EELCMProcessor.doStart(J2EELCMProcessor.java:109)

        at com.sap.engine.services.dc.lcm.impl.LifeCycleManagerImpl.start(LifeCycleManagerImpl.java:80)

        at com.sap.engine.services.dc.cm.deploy.impl.LifeCycleManagerStartVisitor.visit(LifeCycleManagerStartVisitor.java:48)

        at com.sap.engine.services.dc.cm.deploy.impl.DeploymentItemImpl.accept(DeploymentItemImpl.java:84)

        at com.sap.engine.services.dc.cm.deploy.impl.DefaultDeployPostProcessor.postProcessLCMDeplItem(DefaultDeployPostProcessor.java:111)

        at com.sap.engine.services.dc.cm.deploy.impl.DefaultDeployPostProcessor.postProcess(DefaultDeployPostProcessor.java:73)

        at com.sap.engine.services.dc.cm.deploy.impl.DeployerImpl.doPostProcessing(DeployerImpl.java:1135)

        at com.sap.engine.services.dc.cm.deploy.impl.DeployerImpl.performDeploy(DeployerImpl.java:1024)

        at com.sap.engine.services.dc.cm.deploy.impl.DeployerImpl.doDeploy(DeployerImpl.java:819)

        at com.sap.engine.services.dc.cm.deploy.impl.DeployerImpl.deployInternal(DeployerImpl.java:454)

        at com.sap.engine.services.dc.cm.deploy.impl.DeployerImpl.deploy(DeployerImpl.java:228)

        at com.sap.engine.services.dc.cm.deploy.impl.DeployerImplp4_Skel.dispatch(DeployerImplp4_Skel.java:910)

        at com.sap.engine.services.rmi_p4.DispatchImpl._runInternal(DispatchImpl.java:483)

        at com.sap.engine.services.rmi_p4.server.ServerDispatchImpl.run(ServerDispatchImpl.java:83)

        at com.sap.engine.services.rmi_p4.P4Message.process(P4Message.java:72)

        at com.sap.engine.services.rmi_p4.P4Message.execute(P4Message.java:43)

        at com.sap.engine.services.cross.fca.FCAConnectorImpl.executeRequest(FCAConnectorImpl.java:1055)

        at com.sap.engine.services.rmi_p4.P4Message.process(P4Message.java:59)

        at com.sap.engine.services.cross.fca.MessageReader.run(MessageReader.java:55)

        at com.sap.engine.core.thread.execution.Executable.run(Executable.java:122)

        at com.sap.engine.core.thread.execution.Executable.run(Executable.java:101)

        at com.sap.engine.core.thread.execution.CentralExecutor$SingleThread.run(CentralExecutor.java:328)

      Caused by: com.sap.engine.services.ejb3.container.ActionException: Cannot load bean class com.dc.multimap.DCMultiMapBean for component sap.com/DCMultiMap_EAR*xml|DCMultiMap_EJB.jar*xml|DCMultiMap

        at com.sap.engine.services.ejb3.runtime.impl.Actions_BeanClassesInitialization.loadApplicationClass(Actions_BeanClassesInitialization.java:56)

        at com.sap.engine.services.ejb3.runtime.impl.Actions_BeanClassesInitialization.loadApplicationClasses(Actions_BeanClassesInitialization.java:41)

        at com.sap.engine.services.ejb3.runtime.impl.Actions_ComponentInterfacesProviderClassesInitialization.loadApplicationClasses(Actions_ComponentInterfacesProviderClassesInitialization.java:20)

        at com.sap.engine.services.ejb3.runtime.impl.Actions_SessionBeanClassesInitialization.loadApplicationClasses(Actions_SessionBeanClassesInitialization.java:20)

        at com.sap.engine.services.ejb3.runtime.impl.Actions_StatelessBeanClassesInitialization.loadApplicationClasses(Actions_StatelessBeanClassesInitialization.java:18)

        at com.sap.engine.services.ejb3.runtime.impl.Actions_BeanClassesInitialization.perform(Actions_BeanClassesInitialization.java:27)

        at com.sap.engine.services.ejb3.container.CompositeAction.perform(CompositeAction.java:84)

        at com.sap.engine.services.ejb3.container.ApplicationStarter.perform(ApplicationStarter.java:213)

        at com.sap.engine.services.ejb3.container.ContainerInterfaceImpl$Actions.perform(ContainerInterfaceImpl.java:1133)

        … 35 more

      Caused by: java.lang.ClassNotFoundException: com.dc.multimap.DCMultiMapBean

      ————————- Loader Info ————————-

      ClassLoader name: [sap.com/DCMultiMap_EAR]

      Loader hash code: 21d414ef

      Living status: alive

      Direct parent loaders:

         [system:Frame]

         [interface:webservices]

         [interface:cross]

         [interface:security]

         [interface:transactionext]

         [library:webservices_lib]

         [library:opensql]

         [library:jms]

         [library:ejb20]

         [service:p4]

         [service:ejb]

         [service:servlet_jsp]

         [service:engine.security.facade]

         [library:engine.j2ee14.facade]

         [interface:com.sap.aii.af.ifc.facade]

         [service:com.sap.aii.af.svc]

         [library:com.sap.aii.af.lib.facade]

         [service:com.sap.aii.af.svc.facade]

         [service:com.sap.aii.adapter.xi.svc]

      Resources:

         C:\usr\sap\PID\J00\j2ee\cluster\apps\sap.com\DCMultiMap_EAR\EJBContainer\applicationjars\DCMultiMap_EJB.jar

      —————————————————————

        at com.sap.engine.boot.loader.MultiParentClassLoader.loadClass(MultiParentClassLoader.java:280)

        at com.sap.engine.boot.loader.MultiParentClassLoader.loadClass(MultiParentClassLoader.java:249)

        at com.sap.engine.services.ejb3.runtime.impl.Actions_BeanClassesInitialization.loadApplicationClass(Actions_BeanClassesInitialization.java:54)

        … 43 more

      ]

      Result

      Status:Warning

      Would you have something to suggest?

      (0) 
        1. Rafael Vieira

          Hi Praveen,

          Deploy finished successfully this time! Tks a lot!

          However, I’m still seeing error com.sap.engine.interfaces.messaging.api.exception.MessagingException: com.sap.engine.services.jndi.persistent.exceptions720.NameNotFoundException: Object not found in lookup of DCMultiMap.

          Am I referencing module name wrongly in channel config?

          Or what am I doing wrong here?

          This is how JNDI shows the deployed EAR:Screen Shot 2016-08-19 at 2.54.47 AM.png

          And this is how I’m setting up my receiver file channel:

          Screen Shot 2016-08-19 at 2.57.21 AM.png

          I also tried with localejbs/DCMultiMap, but getting same error message.

          Thanks!

          (0) 

Leave a Reply