Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
dominic4
Active Participant
Hello Integrators!

In this blog post, I want to show you how we work with nested calls to enrich data with an external ID from a different source in iFlows.

What are they good for?


Let’s say we want to load contacts to SAP Cloud for Customers, but we do not have the internal ID of the contacts in our source system. To do so, we would need to enrich the data and transfer the internal ID for each existing contact otherwise the system would end up creating a new record. There are many examples like this, where data is in a XML-Structure and the structure needs to be enriched before sending it to a service.

How’s it done?


The idea is to create two branches. In one, you are calling the service with the data you need and in the other one, you are bypassing the original data. After you have joined the two branches together, you start to enrich the bypassed payload with the new data.



Here you see that one branch bypasses the data and one makes a SOAP-Request to get IDs. We use a parallel multicast to create the two flows.

The structure of the nested call: map the message to the structure you need, make the call and extract the data from the payload to a header variable.

After collecting the external IDs, you should write them to a hashmap and save the hashmap in a header variable. Take a look at the “write hashmap” script. Then you can access the data in a script later.

In our case we get XML from the SOAP-Service that we call. We use the XMLSlurper to read it out in a Script.
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {

HashMap<String, String> externalIdMapping = new HashMap<String, String>();

def body = message.getBody(java.lang.String);
def node = new XmlSlurper().parseText(body)

for (i = 0; i < node.ObjectIDMapping.size(); i++) {
externalIdMapping.put(node.ObjectIDMapping[i].RemoteObjectID.text(),node.ObjectIDMapping[i].LocalObjectID.text());
}

message.setHeader("externalIdMapping",externalIdMapping);
message.setBody("");

return message;

}

In this case the hashmap uses a string as key and value. In other cases you can put whole structures and other objects as values.

Don’t forget to delete the body payload because it is not used anymore and you would get problems in the gather element or late when mapping.

After you have joined the flows again and gathered the messages to have the “old” payload and the hashmap header, you can use the hashmap in the next message mapping. Remember: we have an xml structure with an external ID as input but we need the internal ID for the service at the end of our flow.



In a custom function, you can read the data from the hashmap.

In our case the the custom function looks like this:
import com.sap.it.api.mapping.*;

def String customFunc(String arg1, MappingContext context){

HashMap<String, String> externalIdMapping = context.getHeader("externalIdMapping");
arg1 = externalIdMapping.get(arg1);
if ( arg1 == null ) {
arg1="";
}
return arg1
}

Now you have enriched your XML with the external ID from a second source.

Do you have other ideas of implementing nested calls? I think it is also possible to bypass the old payload in a header variable, but, to me, this looks easier to read. Please let me know if you have any questions or suggestions.
5 Comments