Skip to Content
Author's profile photo Sriprasad S Bhat

How to copy data across multiple branches of Multicast in SAP CPI

Introduction:

Recently came across multiple SCN threads looking for how to copy the data across multiple branches of Multicast in SAP CPI, so this is how we can achieve the same with small example using HashMap.

Scenario:

We will be creating below sample scenario where we are passing some test data to multiple branches where each branch has its own set of transformations based on some key value and at the end of the Message processing data from both the branches needs to be merged and sent to Target side.

Step 1:

Content modifier with sample data.

<Root>
	<Record>
		<Field1>F1</Field1>
		<Condition>X</Condition>
		<Field2>F2</Field2>
		<Field3>3</Field3>
	</Record>
	<Record>
		<Field1>F11</Field1>
		<Condition>X</Condition>
		<Field2>F21</Field2>
		<Field3>31</Field3>
	</Record>
	<Record>
		<Field1>F12</Field1>
		<Condition>Y</Condition>
		<Field2>F22</Field2>
		<Field3>32</Field3>
	</Record>
	<Record>
		<Field1>F13</Field1>
		<Condition>X</Condition>
		<Field2>F23</Field2>
		<Field3>33</Field3>
	</Record>
	<Record>
		<Field1>F14</Field1>
		<Condition>Y</Condition>
		<Field2>F24</Field2>
		<Field3>34</Field3>
	</Record>
	<Record>
		<Field1>F15</Field1>
		<Condition>N</Condition>
		<Field2>F25</Field2>
		<Field3>345</Field3>
	</Record>
	<Record>
		<Field1>F16</Field1>
		<Condition>N</Condition>
		<Field2>F26</Field2>
		<Field3>346</Field3>
	</Record>
</Root>

Step 2:

Script to initiate the Hash Map which is used in both the branches.

Script:

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;

def Message processData(Message message) {
    //Body 
     def body = message.getBody();
     def str=body.toString()
    //Initiate HashMap and assign it to Header   
     HashMap<String, String> hmap1 = new HashMap<String, String>();
     message.setHeader("cacheEntity",hmap1);  
  
   return message;
}

Step 3:

Content filter which filters certain set of data in my case data having Condition field value “X”.

Step 4:

In my case I will not be doing much transformation so storing the data after filter into hash map which can be used in second branch.Below Script pulls the hash map that was initialized in Step 2 and overwrites the content of it.

Script:

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;

def Message processData(Message message) {
    //Body 
       def body = message.getBody();
       def str=body.toString()
	   
        def map = message.getHeaders();
	//Get initialized cached entity form Header
	HashMap<String, String> cacheData = map.get("cacheEntity");
	cacheData.put("Branch1",str)
	message.setHeader("cacheEntity",cacheData);
	return message;
}

Step 5:

Content filter which filters certain set of data in my case data having Condition field value “Y”.

Step 6:

Now we have second branch data ready and need to send the data from both the branch together to target system.Below script will do the concatenation of both the data( one set from Branch Y and another from Branch X ).

Script:

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
    //Body 
    def body = message.getBody();
    def map = message.getHeaders();
    def output = map.get("cacheEntity");
    def value=output.get("Branch1")
    def TargetData = "<Output>"+body+value+"<\\Output>"
    
    message.setBody(TargetData);
    return message;
}

Output Generated:

<Output>
	<Root>
		<Record>
			<Field1>F12</Field1>
			<Condition>Y</Condition>
			<Field2>F22</Field2>
			<Field3>32</Field3>
		</Record>
		<Record>
			<Field1>F14</Field1>
			<Condition>Y</Condition>
			<Field2>F24</Field2>
			<Field3>34</Field3>
		</Record>
	</Root>
	<Root>
		<Record>
			<Field1>F1</Field1>
			<Condition>X</Condition>
			<Field2>F2</Field2>
			<Field3>3</Field3>
		</Record>
		<Record>
			<Field1>F11</Field1>
			<Condition>X</Condition>
			<Field2>F21</Field2>
			<Field3>31</Field3>
		</Record>
		<Record>
			<Field1>F13</Field1>
			<Condition>X</Condition>
			<Field2>F23</Field2>
			<Field3>33</Field3>
		</Record>
	</Root>
	<\Output>

Conclusion:

Since the headers or properties set in first branch not accessible in second or further branches above solution will help to overcome that issue.

Thanks to Eng Swee Yeoh  for the wonderful blog where he explains the above behavior with below Conclusion.This still holds good for my blog also.!

Header/Property Object Type Created In Accessible in Subsequent Branch Modifications in Predecessor Branch seen in Subsequent Branch
java.lang.String Main route Yes No
java.util.HashMap Main route Yes Yes
Any Multicast branch No N/A

Thanks Praveen Tirumareddy for your as usual great support:)

Hope this helps SAP CPI beginners!

Regards,

Sriprasad Shivaram Bhat

Assigned Tags

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

      Hi Sri,

      Good one. Keep blogging !

      thanks and regards,

      Praveen T

      Author's profile photo Karthik Bangera
      Karthik Bangera

      Hi Sri,

       

      Good one as always 🙂 Thanks!

       

      Regards,

      Karthik

      Author's profile photo Gagandeep Batra
      Gagandeep Batra

       

      Hi Sri

      Great Work. Thanks For Sharing!!

       

      Regards

      Gagan

      Author's profile photo Sharma Ashwini
      Sharma Ashwini

       

      Thanks Sri.

      Good one as always ? Thanks!

      Regards,

      Ashwini

      Author's profile photo Venu Ravipati
      Venu Ravipati

      Very Nice Blog 🙂

      Thank you..

      Venu

      Author's profile photo Diptee Sawant
      Diptee Sawant

      Hello Sriprasad,

      I tried the scenario as described but the output i get at the end of Step 6 is <Output>net.sf.saxon.dom.DOMNodeList@1e388df4<\Output> and not what is expected.

      Why would this be so? Also, if i initiate and set a Hashmap value inside a sequential multicast branch of a local integration process; will it be readable after the join step in the calling integration process?

       

      Regards,

      Diptee

      Author's profile photo Raj Chintam
      Raj Chintam

      Thanks for the details.  I should have seen this posting little early.  Just recently I ran into a scenario where I need to access hashmap object in a different branch of sequential multicast. After so much of struggle, I eventually realized that I cannot access hashmap from previous branch.

       

      So, I ended up with a workaround of storing that payload. At a later stage, where I needed that data, I used a content modifier to get it back and handed over to the content to next process. (Just not in the form of a hashmap, but in a property value format).