PI REST Adapter – SFSF LMS Integration (OData V4)
We had a requirement to bring in SFSF LMS “Learning Approvals” into SAP HCM and to be able to approve or reject these items from SAP. Although SFSF LMS exposes various entities as OData V4 APIs, when trying to integrate with SAP HCM there were a few questions on the approach:
- Which PI adapter to use – SFSF, OData or REST ?
- How to convert JSON to XML (for processing in PI) and vice versa ?
- How to generate the required XSDs for LMS APIs (for use in mapping)?
A quick search on both PI/PO and Successfactors communities reveals that there has been a lot of work already done covering integration scenarios for SF Bizx, EC and SF LMS (standard SAP delivered content or earlier version of LMS APIs). There is very little information that we could find on how to integrate the latest SFSF OData V4 LMS APIs using SAP PI.
We realised that the best way to answer these questions was to start a POC.
I started off with the NW PI Connectivity add-on 1.0 “SFSF Adapter” and “OData Adapter”. While this is a good starting point, soon I found that there are limitations on how these adapters can be used to consume SFSF LMS APIs. There are many discussions on the SFSF LMS forums on the issues faced in consuming LMS OData V4 using PI/PO.
After going through various “PI REST Adapter” blogs, SAP documentation and looking at the generic nature of the adapter, I decided to give the REST Adapter a try.
The second question, how do we convert the JSON to XML and vice versa? Again there are some wonderful blogs stating how this can be done by using:
- Standard REST Adapter JSON converter or
- Custom module developed by Eng Swee Yeoh
Finally, Creating XSD for the SFSF LMS APIs to carry out the required mapping in PI. The plan was to use Eclipse (Mars) “Modelling operations” to generate the XSDs but again looking at the options available, this was not possible for SFSF LMS APIs.
Eg: When using Successfactors adapter with REST or OdataV4 protocols the “Modelling operation” option is not available and with OData V2 protocol “Modelling operation” does not allow authentication using the SFSF LMS “Client Secret”.
This required a bit more investigation to come up with a set of repeatable steps to generate XSD and which could be potentially applied on other scenarios. The guide will cover the steps I used during this POC.
Scenario
To implement the end-to-end process described above, we will need to create 3 flows:
- First to get the user OAuth token,
- Second use the OAuth token to retrieve the “Learning Approval” items for the user and
- Finally use these items to approve or reject in SFSF LMS from SAP.
This guide will focus on how the second flow is implemented to retrieve “Learning Approval” items from SFSF LMS. Other flows are implemented in similar way but are not covered in this document.
LMS API Used: GET /learning/odatav4/public/user/user-service/v1/learningapprovals
PI Version used for this POC was 7.31 SP 12 (Single stack)
How to generate XSD for SFSF LMS Entities?
Step 1: Using SOAP UI or any other REST client, get the request or response JSON from SFSF LMS
Step 2: Use an online tool to convert JSON to XML. Click here to find out the tool I used.
Step 3: In the generated xml file:
- After the <?xml version=”1.0″ encoding=”UTF-8″ ?> tag, create a <root> and end the file with </root>. An XML file cannot have multiple root nodes.
- Remove any special symbols (eg: @).
- The resultant XML will look like the following
Step 6: Upload and validate the XSD in ESR as External Definition (ED_LearningApproval) for Response.
HINT: Use “root” Message for SI, MM and OM.
Step 7: Repeat the above steps to create the external definition for handling “Requests”. In this flow, we only require an empty XSD to pass the OAuth Token. See ESR steps for more details.
ESR Developments:
Step 1: Create new Data Type and Message Type for both Request and Response as required in the Sender system (SAP HCM).
Request : DT_LearningApprovalRequest, MT_LearningApprovalRequest.
Response : DT_LearningApprovalResponse, MT_LearningApprovalResponse.
Step 2: Create the Outbound and Inbound Service Interfaces (Synchronous)
Inbound:
NOTE: The request External Message is a Dummy XSD with message name “root”. Not to confuse with the Response External message name which also has a message name “root”? – Should have named it differently !
Step 3: Complete the Message Mapping for both request and response.
Request: MT_LearningApprovalRequest to External Definition (empty)
NOTE: In this particular scenario we are going to use the Request mapping to take the OAuth Token to the REST Adapter HTTP Header (Generated in the first flow).
OR Dynamic Configuration could be used to pass Adapter specific values. Choice is yours.
Response: ED_LearningApproval to MT_LearningApprovalResponse
Step 4: Complete “Operation Mapping” connecting both Source and Target Operations
Integration Builder:
Moving on to Integration Builder, we will first configure the channels and use standard REST Adapter JSON to XML conversion.
Sender:
This will be a normal SOAP adapter to the SAP HCM box.
Receiver:
Following shows the REST Adapter configurations.
The “oauth_token” is taken from mapping following XPath and then passed through the HTTP Headers.
There are two options to handle the payload conversion, One could choose between the “Standard REST Adapter” JSON to XML conversion as shown here
OR use the custom module (Custom_AF_Modules/FormatConversionBean) for JSON2XML conversion.
Both options work fine.
Leave the module configuration as default for the standard JSON to XML conversion.
Running the Scenario:
To run the interface, a test ABAP program was created which gets the “User ID” in selection screen and triggers two interface calls into SF LMS.
The initial call is to get the OAuth token and then the second call to retrieve any pending “Approval items” from SF LMS by passing the received OAuth token.
By clicking the “Tap ID” the user will be given option to “Approve” or “Deny” and respective APIs are called(which is the third flow).
The final implementation will be looking at creating SAP Workitems and pushing it to a custom mobile approval app, which is currently used at our site.
Interface Log:
Following shows the request/response log and also shows the JSON to XML conversion of payload using the standard REST Adapter:
Request:
Response:
Payload: Before conversion
Payload: After conversion
Conclusion:
I hope the above approach or parts of it will be useful as a guide to integrate SFSF LMS APIs (OData V4) using SAP PI REST Adapter.
References:
SAP NetWeaver Process Integration, connectivity add-on 1.0 SP01
Learning OData API Reference
PI REST Adapter – Blog Overview
OData Adapter and SFSF Adapter (extensions) for SAP Process Integration
Successfactor (LMS) Integration with HCM system Using SAP PI
REST Adapter in PI/PO: Enhanced XML/JSON Conversion
JSONTransformBean Part 1: Converting JSON content to XML
Eclipse Modelling Operations
XML Schema Definition Tool (Xsd.exe)
Hello Ravi,
Very helpful Blog.
I am trying to integrate Successfactors LMS and SAP.
for the Curriculum Status interface I need to connect to the SAP via an OData adapter which will consume the SICF service HRSFI_Qualification_Srv
I am able to login to the service when i try Test Service from the SICF TCODE in ECC manually. It is giving the response.
But when the same is tried from the channel Ping it is giving me Error 403- Forbidden.
Is there any other setting that I need to make in PI in order to make the service accessible.
Any help is really appreciated.
Thanks,
Priyank Shrivastava
Hi Priyank - Sorry for this late response, I was away for quite some time now.
Not sure if your question is still valid, I personally havent tried this scenario but assume the channel is configured properly with all required entries.
Error 403 shows that the request is reaching the server but failed to authenticate or progress further.
Thanks,
Ravi G.
Hi Ravi
It’s interesting how “what goes around, comes around”.
I was recently assessing the feasibility of consuming SF LMS’s new OData v4 services using PI, and one of my searches brought me to this blog. It’s interesting to see your own journey and what you came up with.
As for myself, initially the SFSF adapter with the REST protocol looks promising as it seem to be developed for LMS integration. After many trial and error sessions, I thought I was going to hit the jackpot, until alas I hit the final one that made me conclude that I can’t proceed with it – it was the JSON/XML conversion built into the adapter.
The OAuth worked fine, and even I might be able to hack something to generate the XSD because HCI’s Operation Modeler do not support OData v4. But the JSON/XML conversion was not something I could not change since it was built into the adapter and not as a separate module. The SF LMS service that I was trying out (Learning Events) require arrays in the JSON as well as certain fields represented as integers or booleans and not all being strings. The adapter could not handle both of these. It is such a shame that it fit 95% except only the last bit.
Unfortunately also, the SFSF adapter do not have the same capability as the REST adapter where it allowed enhanced customization of the JSON/XML conversion.
An interesting fact is the REST adapter uses Jettison JSON library while the SFSF adapter uses Google GSON library. Amazing how SAP’s developers do not talk to one another!!
Regards
Eng Swee
Hi Eng
I am currently working on Integrating SF LMS using SFSF REST adapter. I am not able to pass the filter criteria to the API. I tried hardcoding as well tried to send it dynamically. Both ways it errored out.
The LMS Service I am trying to access is SearchStudents which takes filter criteria as isActive=true.
Looks like you have already achieved that part. Any inputs will be highly appreciated.
I have built a synchronous interface to fetch the active students. So Its my receiver channel that's talking to LMS.
Tried
learning/odatav4/searchStudent/v1/Students?$filter=criteria/isActive%20eq%20true
and also tried
learning/odatav4/searchStudent/v1/Students and passed $filter=criteria/isActive%20eq%20true in QueryStringOptions datatype.
SAP help says QueryStringOptions is only supported for OData. Not sure how to send dynamic query in REST protocol.
Regards
Sonal
Hello all,
I'm trying to get the connection working with SFSF LMS working.
1st how can i check LMS is conffigured correctly?
I am testing with soap ui to make sure the connections are working.
The Get token is not working and i can not figure out why not.
Filed in the Client ID ...ID from LMS
https://BLABLA.plateau.com/learning/oauth-api/rest/v1/token
Scope: {"userId":"PLATEAU","companyId":"BLABLA","userType":"admin","resourceType":"learning_public_api"}
Client Secet: from LMS
SOAPUI log...
017-05-03 17:34:54,005 ERROR [SoapUI] An error occurred [org.apache.oltu.oauth2.common.exception.OAuthSystemException: OAuthProblemException{error='unsupported_response_type', description='Invalid response! Response body is not application/json encoded', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}], see error log for details
2017-05-03 17:34:54,005 ERROR [errorlog] Error retrieving OAuth 2 access token
2017-05-03 17:34:54,005 ERROR [errorlog] com.eviware.soapui.impl.rest.actions.oauth.OAuth2Exception: org.apache.oltu.oauth2.common.exception.OAuthSystemException: OAuthProblemException{error='unsupported_response_type', description='Invalid response! Response body is not application/json encoded', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}
com.eviware.soapui.impl.rest.actions.oauth.OAuth2Exception: org.apache.oltu.oauth2.common.exception.OAuthSystemException: OAuthProblemException{error='unsupported_response_type', description='Invalid response! Response body is not application/json encoded', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}
at com.eviware.soapui.impl.rest.actions.oauth.OltuOAuth2ClientFacade.logAndThrowOAuth2Exception(OltuOAuth2ClientFacade.java:105)
at com.eviware.soapui.impl.rest.actions.oauth.OltuOAuth2ClientFacade.requestAccessToken(OltuOAuth2ClientFacade.java:50)
Very good Blog!!
Is there any new simple way to send oauth token?
I would like the consumer to call the SAP PI without worrying about authentication with the LMS. SAP PI would take the token and pass it on to the next call without requiring a new consumer request.