Cloud Integration, SAP Integration Suite, SAP Cloud Platform Integration

Propagate Hashmap values from primary iflow to secondary iflow using Soap adapter in SAP Cloud Integration

Introduction:

In various requirements in SAP Cloud Integration( SAP CPI) we need to use HashMap (key-value pair) to assign values at message mapping runtime using groovy scripts.

Here, We use groovy scripts to initialize, load and get values from hashmaps.

Now, In a scenario where we have created a hashmap object in the main Iflow(Primary iflow) and from main iflow we need to call another secondary iflow (say subiflow) via soap adapter( for one way communication).And we need to use the hashmap values set on the primary iflow passed over to secondary iflow by leveraging Allowed Header(s) Runtime Configuration of an iflow,so that Hashmap values can be used on secondary iflow’s message mapping.

However, when we pass any Hashmap values through Allowed Headers(s) option from primary iflow to secondary iflow via soap channel,we need to again reload the hashmap object to make it usable on message mapping via groovy script. Here, I have explained how to achieve this functionality with step by step process.

I have leveraged the use of a groovy scripts to initialize, load and get values from hashmap.

While demonstrating the step by step process, we may go through few important technical aspects as below:

  1. Passing values of setHeader object from one iflow to another.
  2. One way communication from primary iflow to another sub-iflow using soap adapter.
  3. Retrieve value of setHeader object into secondary iflow(sub-iflow) using getHeader object.
  4. Reloading Header object with Hashmap values into secondary iflow.

This sample process can be leveraged by developers to edit, modify and enhanced according to other business requirements as well.

Prerequisites: You should have CPI tenant access and have understanding on Integration flow development.

Design approach: To explain these scenario, I have created two sample iflows (1st the Primary iflow which we call as main iflow and 2nd one as secondary iflow which we call as subiflow).

Main Iflow Processing :

Below Figure1 will show the high level steps performed on the Primary(main) iflow:

Figure 1 : Main Iflow(Primary Iflow Steps)

Detailed Steps of Main Iflow (Figure1) as below:

Step1(Figure1): Start Timer Event : This is to run once the main iflow on deploying

Step2/Step3/and Step4 (Figure2): Request Reply/SuccessFactors Channel/and Receiver component: These steps are used to call SuccessFactors system using SuccessFactors Odata adapter to get/fetch values from an SF entity .In our example, we are using SF odata entity “PicklistOption” as below:

SF Channel Configuration Screenshot

Here, as an example we are retrieving values for Picklist “personRelationshipType”

Step 5(Figure2:): Groovy Script : Below groovy script is used to Initialize Hashmap object “PicklistID_ExternalCode_Label” and load hashmap by looping on the incoming Picklist values from “PicklistOption” entity by creating key and value pairs assignments. After loading the Hashmap table object, finally hashmap object is assigned to a Property name “PicklistID_ExternalCode_Label”

Here Key = picklistId+”_”+externalCode ( say: personRelationshipType_2)

and Value = localeLabelValue ( say: Child)

(Note: I have kept same name for hashmap object and Property name)

/*This script is used for storing picklist values in a Hash Map*/
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.xml.XmlUtil;
import groovy.util.XmlSlurper;
def Message processData(Message message) {    
// HashMap initialisation to load Picklist external code to label
HashMap<String,String> PicklistID_ExternalCode_Label  = new HashMap<String,String>();
PicklistID_ExternalCode_Label.put("Dummy", "Dummy");

	def body = message.getBody(java.io.Reader);
	def list = new XmlSlurper().parse(body)
	def map = message.getProperties();

	list.PicklistOption.each {

		String picklistId = it.picklist.Picklist.picklistId.text();
		String externalCode = it.externalCode.text();
		String localeLabelValue = it.localeLabel.text();
		String keyObj = picklistId+"_"+externalCode;

		PicklistID_ExternalCode_Label.put(keyObj,localeLabelValue);
	}
	message.setProperty("PicklistID_ExternalCode_Label",PicklistID_ExternalCode_Label);
	return message;
}

Groovy Script Code Snippet (Initialize & Load Hashmap into a Property)

Step6(Figure1) : Content Modifier: Use to Assign Property value “PicklistID_ExternalCode_Label” to a Header value “PicklistID_ExternalCode_Label” which will be used in Allowed Headers(s:) Runtime Configuration to pass to any secondary iflow.

Note: Here Property and Header defined with same name.

Set Header value from HashMap property value

Step7/Step8/Step9/and Step10 (Figure2): Request-Reply/Soap Receiver Channel/ Receiver Component(for SubIFlow call) and Message end step. These steps are used to call the secondary iflow using soap receiver channel. Configuration done at channel mentioned on below images.

Soap Receiver Channel for calling Secondary iflow(Subiflow)

Updating the Allowed Header(s) Runtime Configuration on Main iflow: This is used to pass the Header values to the Secondary iflows as below:

Set Allowed Header Runtime Configuration Primary Iflow

Secondary/Sub-Iflow Processing :

Below Figure2 will show the high level steps performed on the Secondary(SubIflow) iflow:

Figure 2 : Secondary Iflow (Sub Iflow Steps)

Detailed Steps of Secondary Iflow (Figure 2) as below:

Step1 and Step 2(Figure2): Sender Component and Sender Soap Channel: These sender configuration used to receive data from the Main iflow step demonstrated above as a one way communication and no response will be sent back to main iflow.

Sender Channel Configurations are as below(Refer figure 3):

Figure 3:Sender Soap Channel Configuration SubIflow

Step3 (Figure2) : Groovy Script to reload the Hashmap Header values: This is the main script which is used to reload the Hashmap Header with Hashmap values from the Header values received from Allowed Header Runtime Configuration from Main iflow to Sub Iflow.

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
	
	def messageLog = messageLogFactory.getMessageLog(message);
// Get Header Hashmap from Main Process flow and replace with local hashmap header values
def Headers = message.getHeaders();
String value = Headers.get("PicklistID_ExternalCode_Label");

value = value.replaceAll("=,", "=Null,"); // Replace blank key values with Null word
//value = value.replaceAll(", ", ","); //// Replace comma and blank with only comma
value = value.substring(1, value.length()-1);           //remove curly brackets
String[] keyValuePairs = value.split(", ");              //split the string to creat key-value pairs
Map<String,String> map = new HashMap<>();               
for(String pair : keyValuePairs)                        //iterate over the pairs
{
    String[] entry = pair.split("=");                   //split the pairs to get key and value 
    map.put(entry[0].trim(), entry[1].trim());          //add them to the hashmap and trim whitespaces
}

message.setHeader("PicklistID_ExternalCode_Label", map)
return message;
}

This code Snippet used to retrieve Header values and again reload the Hashmap Header using setHeader object.

Here, we are replacing blank hashmap value assignment with value “Null” to handle transformation while retrieving values on message mapping level on subsequent step.

Below trace shows value from Allowed Headers with name “PicklistID_ExternalCode_Label” before applying the above groovy script:

Header Value retrieved from Allowed Header Runtime Configuration from Main flow before applying groovy script step3 of Figure 3.

Below trace shows value from converted Hashmap Headers with name “PicklistID_ExternalCode_Label” after applying the above groovy script:

Header Hashmap Value after applying groovy script step3 of Figure 3.

Step4(Figure2) : Allowed Header(s:) Runtime Configuration : This parameter section is used to maintain the Header names with the same Header name set on main iflow to retrieve values from Main Iflow and groovy script defined at Step 3(Figure2) will use this Header name for getHeaders() for processing.

Step5(Figure2) : Content Modifier: used for testing purpose to maintain test payload on message Body as below

<Records>
	<Rows>
		<PicklistTypeCode>10</PicklistTypeCode>
	</Rows>
	<Rows>
		<PicklistTypeCode>99</PicklistTypeCode>
	</Rows>
</Records>

Test xml input payload.

Step6(Figure2) : Message Mapping : used to show how to retrieve values from SetHeader Hashmap defined on previous step on message mapping transformation. A groovy script is used to retrieve the value from stored Hashmap object by passing key for Hashmap input.

import com.sap.it.api.mapping.*;
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.xml.XmlUtil;
import groovy.util.XmlSlurper;

def String GetPerPersonRelationShipLocalLabel(String picklistId,String externalCode,MappingContext context) 

{ 
    String myKey = "";
    String Outputvalue = "";
HashMap<String,String> pickListMap = context.getHeader("PicklistID_ExternalCode_Label");
  
   myKey = picklistId+"_"+externalCode;
   Outputvalue = pickListMap.get(myKey);
   
	if (Outputvalue == null || Outputvalue == "Dummy" || Outputvalue == "" || Outputvalue  == "Null" )   
		
		{
	Outputvalue = "";
	
    }
    
return Outputvalue;


}
Message Mapping using groovy script to retrieve Header values

Here passing two inputs to groovy scripts which forms a key for Hashmap( Constant “personRelationshipType” and field value from input xml field “PicklistTypeCode”).

Output Payload:

<?xml version="1.0" encoding="UTF-8"?>
<Records>
	<Rows>
		<PicklistTypeCode>10</PicklistTypeCode>
		<HashMapRetrivedTypeValue>Separated / Divorced Partner</HashMapRetrivedTypeValue>
	</Rows>
	<Rows>
		<PicklistTypeCode>99</PicklistTypeCode>
		<HashMapRetrivedTypeValue/>
	</Rows>
</Records>
Rating: 0 / 5 (0 votes)

Leave a Reply

Your email address will not be published. Required fields are marked *