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: 
Former Member

Introduction

Integration with cloud services, e.g. SuccessFactors and Salesforce, can present some challenges.  The basic challenge is the retrieval of the session-id, and then uses it in our request.  This requires a 2-step process:  login to the cloud service to retrieve the session-id, and then use the session-id to send the request.  Customarily, we will have to create a business process using either BPM or ccBPM to accomplish the 2 steps.
In this blog, we will use another alternative which does not require the use of BPM or ccBPM.  This is to use a user-defined function in Message Mapping.

Limitation

The limitation of this method is that service request to be sent must be accomplished with one call.  If multiple calls are required, then BPM or ccBPM will have to be used.  An example of when multiple requests are needed is when we query an object in SuccessFactors, the query will return only a subset of the resultset.  A queryMore request will have to be used and looped to retrieve the remainder of the resultset.

Concept

When a web service request is sent to the cloud application, the session-id will have to be used.  This session-id is obtained with a “login” request, using userid and password and companyid (if SuccessFactors).
This login request can be done either using a traditional synchronous integration interface, or using a “lookup” in Message Mapping.  Since “lookup” in Message Mapping is only available for JDBC and RFC, we have to develop our own for web service (SOAP).
By using the “lookup” we can avoid creating a separate integration and BPM/ccBPM.
For this blog, we will use SuccessFactors as an example.

User-Defined function

Below is the UDF I used:  (I created a Function Library to contain the UDF, so that it can be used in multiple Message Mappings.)
Please note:
  1. The request string is obtained from the WSDL which can be obtained from the cloud application.  In this example, from SuccessFactors.  The response string, to be parsed, can also be obtained from the WSDL.  To ease the process, I used soapUI to perform the login request, which allows me to examine the contents of both the request and response easily.
  2. Include 2 additional imports in the UDF:
    • Javax.xml.parsers.*
    • Org.w3c.dom.*
  3. A Channel Parameter, SFLogin, is used to make the web service call.  The communication channel will have to be configured in the Integration Directory.  Hard-coding the communication channel in the UDF can also be used, to avoid using the parameter.
The java code is below:
public String GetSessionid(String companyid, String username, String password, Channel SFLogin, Container container) throws StreamTransformationException{
String request = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    +"<ns1:login xmlns:ns1=\"urn:sfobject.sfapi.successfactors.com\">"
    +"<ns1:credential><ns1:companyId>"+companyid+"</ns1:companyId><ns1:username>" 
    +username+"</ns1:username><ns1:password>"+password+"</ns1:password>"
    +"</ns1:credential></ns1:login>";
InputStream isRequest = new ByteArrayInputStream(request.getBytes());
SystemAccessor accessor = null;
String sessionid = "";
Try {
/*
     1. Determine a channel.
                        channel information can be hard-coded here
         Channel SFLogin = LookupService.getChannel("BusComp", "CommChan");
*/
    // 2. Get a system accessor for the channel.
    accessor = LookupService.getSystemAccessor(SFLogin);

    // 3. Create a payload according to the data type which the adapter exspects.
    //       Use service.getBinaryPayload() for binary payload,
    //    and service.getTextPayload() for text payloads.
    Payload payload = LookupService.getXmlPayload(isRequest);

    // 4. Execute lookup.
    Payload result = accessor.call(payload);

    //Parse response
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    InputStream resStream = result.getContent();
    Document document = builder.parse(resStream);
    NodeList respNodes = document.getElementsByTagName("result");
    Node node = respNodes.item(0);
    Element element = (Element) node;
    sessionid = element.getElementsByTagName("sessionId").item(0).getChildNodes().item(0).getNodeValue();
}
catch (Exception e) {
        return e.getMessage();
} finally {
    try {
        if (accessor != null) accessor.close();
    } 
    catch (Exception e) {
        return e.getMessage();
    }
}

return sessionid;

}

Testing

The “display queue” in Message Mapping is used to perform the test:
As you can see, the session-id is return during mapping, and can be used in mapping to send our request to SuccessFactors.
14 Comments