SFAPI lookups on SuccessFactors
This document is about, performing lookups on SuccessFactors, when data is exposed using SFAPI.
Lookups are possible using SFSF receiver channel (Adapter – SFSF, Message protocol -SOAP). Please check Prabhat Sharma‘s blog Successfactors communication channel supports UDF based Lookups. Let’s say for an interface, we process all employees. If there are thousands of employees, we have to perform thousands of lookups. To avoid it, we will retrieve all values in one lookup and perform multiple search on response. Instead of SELECT externalCode, name_en_US FROM FO_company WHERE externalCode = ‘110’, we will use SELECT externalCode, name_en_US FROM FO_company to retrieve entire XML.
For each employee we will get ‘externalCode’, we have to send corresponding ‘name_en_US’ to output.
Solution :-
Create receiver SFSF channel.
Mapping :-
First input parameter to udf_LookupSF_SFAPI is a constant – <urn:query xmlns:urn=’urn:sfobject.sfapi.successfactors.com’><urn:queryString>SELECT externalCode, name_en_US FROM FO_company</urn:queryString></urn:query>
Second input parameter is a constant – externalCode
Third input parameter is a constant – name_en_US
Fourth input parameter is element where externalCode values is present in input – company
UDF 1 :- udf_LookupSF_SFAPI : Execution Type: ‘Single Value’
public String udf_LookupSF_SFAPI(String query, Container container) throws StreamTransformationException {
//This UDF will execute 'query' on SuccessFactors cloud server and response XML is sent out as output string.
try {
//Connect to SuccessFactors using SFSF receiver channel.
SystemAccessor accessor = LookupService.getSystemAccessor(LookupService.getChannel("SuccessFactors", "BC_EmployeeCentral", "CC_SFSF_SFAPI_RCVR_Lookup"));
//Send query to SuccessFactors server.
XmlPayload payloadRequest = LookupService.getXmlPayload(new ByteArrayInputStream(query.getBytes()));
Payload payloadResponse = accessor.call(payloadRequest);
//Get response XML from web-service.
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(payloadResponse.getContent()));
StringBuilder response = new StringBuilder();
String line = "";
while (line != null) {
response.append(line);
line = bufferedReader.readLine();
}
//'response' will have XML response from SuccessFactors.
//Now we can use DOM or SAX or Regurlar expressions to perform the lookup on this response string.
return response.toString();
} catch (Exception ex) {
throw new StreamTransformationException(ex.getMessage());
}
}
UDF 2 :- udf_SearchInResponse : Execution Type : ‘All Values of Queue’
public void udf_SearchInResponse(String[] xml, String[] element1, String[] element2, String[] values, ResultList result, Container container) throws StreamTransformationException {
//This UDF will search for element1 in 'xml' and return corresponding element2.
try {
org.w3c.dom.Document doc = javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new org.xml.sax.InputSource(new ByteArrayInputStream(xml[0].getBytes("utf-8"))));
javax.xml.xpath.XPath xPath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
org.w3c.dom.NodeList nlElement1 = (org.w3c.dom.NodeList) xPath.evaluate("//" + element1[0], doc.getDocumentElement(), javax.xml.xpath.XPathConstants.NODESET);
org.w3c.dom.NodeList nlElement2 = (org.w3c.dom.NodeList) xPath.evaluate("//" + element2[0], doc.getDocumentElement(), javax.xml.xpath.XPathConstants.NODESET);
//Lookup Map will contain key value pair of element1 and element2.
Map<String, String> lookupMap = new HashMap<String, String>();
for (int i = 0; i < nlElement1.getLength(); i++) {
lookupMap.put(nlElement1.item(i).getTextContent(), nlElement2.item(i).getTextContent());
}
//If input = ContextChange, then output = ContextChange.
lookupMap.put(ResultList.CC, ResultList.CC);
//Write corresponding value of key to output ResultList.
for (String key : values) {
String value = lookupMap.get(key);
if (value == null) {
result.addValue(key); //If there is no lookup value, output = input.
} else {
result.addValue(value);
}
}
} catch (Exception ex) {
throw new StreamTransformationException(ex.toString());
}
}
Display Queue in Message Mapping :-
Advantages of this approach :-
1. Session management is handled by receiver SFSF channel.
2. Easy to maintain proxy details in receiver SFSF channel.
3. UDF and receiver SFSF channel can be reused for more lookups.
Related blogs :-
How to Model Successfactors SOAP and ODATA Entities using Eclipse Juno Tool.
Testing Integration with SuccessFactors SFAPI
Nice blog... 🙂
Hi Raghu,
before calling these look ups...do we need to call log in request to Success factors and need to get the session id
Thanks
Mahesh.
Mahesh,
Session handling is done by SFSF receiver channel (we don't need to do it).
Hi Raghu,
Could you please provide Full UDF code used for :
udf_LookupSF_SFAPI
udf_SearchInResponse
I have a requirement to use SFSF-OData protocol to fetch data from multiple entities say 3 entities.
I believe we can poll data through 1st Channel using SFSF adapter(odata protocol) and get the initial payload in mapping and will do 2 lookups using other 2 SFSF receiver channels as mentioned in your blog to bring back the response into mapping and filter all conditions in mapping itself.
Let me know if any other solution if more feasible.
Regards
Deepak
Hi Deepak,
I have a same type of requirement where I have to call 2 Entities using SFSF-OData protocol. Do you have the UDF for this?
Thanks,
Poushali
Hello Raghu,
In the above example you have one key and value ( total 2 columns) using hashmap.I have a requirement to get multiple column values corresponding to each key and need to fetch those values How can I achieve this.
For example : emp Id, first name, last name
1 John Joseph
2 Sunil K
Regards,
Tibin