EDUCAÇÃO E TECNOLOGIA

Fetching picklists from SuccessFactors and implementing custom lookup using Groovy Script in CPI

In this blog, we will see how a SuccessFactors picklist lookup can be implemented and consume the picklist <key – value> pairs in the incoming XML and further message processing using SAP cloud platform integration in details.

Here, we will generate the output XML as shown below from input XML, where the values of three XML elements will be replaced with their keys.

In this case, values of TITLE, BLOOD_GROUP and Address_type fields need to be updated from picklists salutation, bloodGroup and addressType respectively.

It is important to understand that the <key-value> pair for addressType and salutation picklists would be <OptionId – en_US> but in case of bloodGroup picklist, <key-value> pair would be <external_code – en_US>. This difference can found in Groovy Script in step7.

Example of a few picklists exported from SuccessFactors:

The picklists pairs are highlighted which are being consumed in our scenario.

The complete iFlow which is further explained step by step, here it is just to give you an overview that there’re basically two Local Integration Processes:

  • In first Local Integration Process(SF Picklist from lookup), we are fetching the required picklists in XML format and storing the same in global variable in CPI.

Alternative: You can also design a separate iFlow for SF lookup according to your business requirement.

  • In second Local Integration Process(Picklist Conversion), the required output XML message is generated by modifying the data with the help of custom object(Groovy Script).

Step1:

  • Start Timer 1 will trigger the execution of local process call SF Picklist from lookup.
  • Request Reply sfapi call is used to query the picklists from SuccessFactors using below configuration:

Step2:

  • Printing the XML payload fetched from SuccesFactors as an attachment using below code:
import com.sap.gateway.ip.core.customdev.util.Message; import java.util.HashMap; def Message processData(Message message) { def body = message.getBody(java.lang.String) as String; //get message body as String def messageLog = messageLogFactory.getMessageLog(message); if(messageLog != null){ messageLog.setStringProperty("Logging#1", "Printing Payload As Attachment") //set property for log messageLog.addAttachmentAsString("SF_Picklist:", body, "application/xml"); //generate attachment with content type application/xml } return message; } 

Result: The screenshot of XML payload attachment is provided below which contains various picklists.

Step3:

  • Store Picklist is variable which is configured to store picklist payload globally in CPI.

Result: Globally stored variable. Now we are open to consume this variable from any of the iFlows running in CPI.

Step4:

  • After a successful execution of local integration call, processing of content modifier Sample input payload in Main Integration Flow will take place.

Below sample input payload in XML format is passed for further processing. You can also connect to an external system for input XML data.

Step5:

  • We also need to check whether required input payload is coming or not as per our requirement. Here We’re checking if results XML tag is coming with data.

  • An attachment is generated for input payload which already shown in previous step.
  • A local integration call is processed for picklist conversion described in next step.

Step6:

  • In content modifier GV Picklist, a property is created to access the picklists from global variable which was stored in step3.

  • Input payload coming from Main Integration Flow is passed further as it is.

Step7:

  • Below Groovy Script is provided which is basically accessing the XML picklists from message property and input payload from message body.

Note: OptionId is represented by id in Groovy Code.

import com.sap.gateway.ip.core.customdev.util.Message; import java.util.HashMap; import groovy.xml.XmlUtil; import groovy.util.XmlParser; def Message processData(Message message) { //message Body def records = message.getBody(java.lang.String) as String; //accessing Global_picklist from Properties def map = message.getProperties(); def picklist = map.get("Global_Picklist"); // Define XML parser and builder for picklist and records def xlm_records = new XmlParser().parseText(records); def xml_picklist = new XmlParser().parseText(picklist); //getting picklist values in HashMaps------------------------------------------------------------ //bloodGroup HashMap<String, String> bloodGroup = new HashMap<String, String>();	//create a new Hashmap object xml_picklist.PicklistOption.findAll { p -> p.picklistId[0].text().toString().equals("bloodGroup") //finding all bloodGroup picklistid entities }.each { p -> bloodGroup.put(p.externalCode[0].text().toString(),(p.en_US[0].text().toString().toUpperCase())) //put all key(externalCode) value(en_US->UpperCase) pairs in Hashmap } //salutation HashMap<String, String> salutation = new HashMap<String, String>();	//create a new Hashmap object xml_picklist.PicklistOption.findAll { p -> p.picklistId[0].text().toString().equals("salutation") //finding all salutation picklistid entities }.each { p -> salutation.put(p.id[0].text().toString(),(p.en_US[0].text().toString().toUpperCase())) //put all key(id) value(en_US->UpperCase) pairs in Hashmap } //addressType HashMap<String, String> addressType = new HashMap<String, String>();	//create a new Hashmap object xml_picklist.PicklistOption.findAll { p -> p.picklistId[0].text().toString().equals("addressType") //finding all addressType picklistid entities }.each { p -> addressType.put(p.id[0].text().toString(),(p.en_US[0].text().toString().toUpperCase())) //put all key(id) value(en_US->UpperCase) pairs in Hashmap } //Updating corresponding keys into the xml records--------------------------------------------------------- //loop for multiple records in message body int result_size = xlm_records.results.size(); int count = 0; while(count < result_size) { //----------------------------------------Blood group--------------------------------------------------------------------- def check_exist_bloodGroup = xlm_records.results[count].BLOOD_GROUP.isEmpty(); // Checking if exists if(check_exist_bloodGroup.toString().equals("false")){ def temp_variable = xlm_records.results[count].BLOOD_GROUP.text().toString().toUpperCase();	//get value of blood Group in UpperCase in temp_variable for (Map.Entry<String, String> entry : bloodGroup.entrySet()) {	//looping bloodGroup Hashmap to search corresponding value if(entry.getValue().equals(temp_variable)){ //Finding value of temp_variable in corresponding hashmap def lv_val = entry.getKey().toString(); //access and store corresponding key in lv_val variable xlm_records.results[count].BLOOD_GROUP[0].value = lv_val;	//replace value of particular xml element with unique key } } } //IF End for Blood group //-------------------------------------------Salutation------------------------------------------------------------------------- def check_exist_saluation = xlm_records.results[count].TITLE.isEmpty(); // Checking for Title, is exists if(check_exist_saluation.toString().equals("false")){ def temp_variable = xlm_records.results[count].TITLE.text().toString().toUpperCase();	//get value of Title in UpperCase in temp_variable for (Map.Entry<String, String> entry : salutation.entrySet()) {	//looping bloodGroup Hashmap to search corresponding value if(entry.getValue().equals(temp_variable)){ //Finding value of temp_variable in corresponding hashmap def lv_val = entry.getKey().toString(); //access and store corresponding key in lv_val variable if(lv_val.contains("-")){ lv_val = entry.getKey().toString().split("-");	//removing unwanted piece of from string if any xlm_records.results[count].TITLE[0].value = lv_val[1]; //replace value of particular xml element with unique key } else{ xlm_records.results[count].TITLE[0].value = lv_val; } } } } //IF End for TITLE //-------------------------------------------Address_type------------------------------------------------------------------------- def check_exist_addresstype = xlm_records.results[count].Address_type.isEmpty(); // Checking for Title, is exists if(check_exist_addresstype.toString().equals("false")){ def temp_variable = xlm_records.results[count].Address_type.text().toString().toUpperCase();	//get value of Title in UpperCase in temp_variable for (Map.Entry<String, String> entry : addressType.entrySet()) {	//looping bloodGroup Hashmap to search corresponding value if(entry.getValue().equals(temp_variable)){ //Finding value of temp_variable in corresponding hashmap def lv_val = entry.getKey().toString(); //access and store corresponding key in lv_val variable if(lv_val.contains("-")){ lv_val = entry.getKey().toString().split("-");	//removing unwanted piece of from string if any xlm_records.results[count].Address_type[0].value = lv_val[1]; //replace value of particular xml element with unique key } else{ xlm_records.results[count].Address_type[0].value = lv_val; } } } } //IF End for TITLE count++; } // Generating response payload attachment def newXml = XmlUtil.serialize(xlm_records); def messageLog = messageLogFactory.getMessageLog(message); if(messageLog != null){ messageLog.setStringProperty("Logging#1", "Printing Payload As Attachment") messageLog.addAttachmentAsString("XMLresponse:", newXml, "text/plain"); } //Set output with the upadted xml message.setBody(newXml); return message; } 
  • The key-value pairs are stored in Hashmap as described in the code.

Result: The output payload produced by the above Groovy Script is the final required XML payload which is then printed as an attachment by custom Groovy code as follows:

In this way, we have called the picklists from SuccessFactors in XML format, stored in the global variable of SAP CPI, passed a sample XML payload for message processing then accessed picklists from global variable in a newly created property and finally XML payload is modified as required with the help of custom object Groovy Script.

You can utilize the above design and Groovy codes according to your requirement.

Thanks and Regards,

Ravi Jangra