Technical Articles
Payload structure for SuccessFactors Upsert in SAP Cloud Integration
The SuccessFactors OData V2 Receiver adapter enables you to communicate with the SuccessFactors system. The Upsert operation is an SAP SuccessFactors function import to update or insert records. SuccessFactors OData V2 receiver supportes Upsert with content-type : atom+xml only.
This blog covers the payload structure for Upsert operation in SAP Cloud Integration.
1. Simple Upsert
Upsert payload schema
<EntitySetName>
<EntityTypeName>
<propertyN>..</propertyN>
...
</EntityTypeName>
<EntityTypeName>
<propertyN>..</propertyN>
...
</EntityTypeName>
</EntitySetName>
Upsert payload sample
<User>
<User>
<status>active</status>
<userId>CaptainAmerica</userId>
<username>CaptainAmerica</username>
<firstName>Steve</firstName>
<lastName>Rogers</lastName>
<city>Brooklyn</city>
<state>New York</state>
<country>USA</country>
</User>
<User>
<status>active</status>
<userId>SpideMan</userId>
<username>SpideMan</username>
<firstName>Peter</firstName>
<lastName>Parker</lastName>
<city>Queens</city>
<state>New York</state>
<country>USA</country>
</User>
</User>
2. Upsert with Deep Insert
Schema
<EntitySetName>
<EntityTypeName>
<propertyN>..</propertyN>
<NavigationPropertyName1>
<NavigationEntityTypeName1>
<PropertyOfNavigation1>..</PropertyOfNavigation1>
</NavigationEntityTypeName1>
</NavigationPropertyName1>
<NavigationPropertyName2>
<NavigationEntityTypeName2>
<PropertyOfNavigation2>..</PropertyOfNavigation2>
</NavigationEntityTypeName2>
</NavigationPropertyName2>
</EntityTypeName>
</EntitySetName>
Deep Insert Sample
<User>
<User>
<status>active</status>
<userId>SpideMan</userId>
<manager>
<User>
<userId>IronMan</userId>
<status>active</status>
<username>IronMan</username>
<firstName>Tony</firstName>
<lastName>Stark</lastName>
</User>
</manager>
</User>
<User>
<status>active</status>
<userId>Thor</userId>
<hr>
<User>
<userId>NickFury</userId>
<status>active</status>
<username>NickFury</username>
</User>
</hr>
</User>
</User>
3. Upsert with Links
NOTE: Linking multiple Entities with pipe(|) symbol is not supported in SuccessFactors OData adapter.
Schema
<EntitySetName>
<EntityTypeName>
<propertyN>..</propertyN>
<link>
<NavigationPropertyName1>
<NavigationEntityTypeName1>
<keyOfNavigation1>..</keyOfNavigation1>
</NavigationEntityTypeName1>
</NavigationPropertyName1>
<NavigationPropertyName2>
<NavigationEntityTypeName2>
<keyOfNavigation2>..</keyOfNavigation2>
</NavigationEntityTypeName2>
<NavigationEntityTypeName2>
<keyOfNavigation2>..</keyOfNavigation2>
</NavigationEntityTypeName2>
</NavigationPropertyName2>
</link>
</EntityTypeName>
</EntitySetName>
Upsert with links Sample
<User>
<User>
<userId>Hulk</userId>
<status>active</status>
<firstName>Bruce</firstName>
<lastName>Banner</lastName>
<link>
<manager>
<User>
<userId>NO_MANAGER</userId>
</User>
</manager>
<matrixManager>
<User>
<userId>matrixManager1</userId>
</User>
<User>
<userId>matrixManager2</userId>
</User>
</matrixManager>
<customManager>
<User>
<userId>customManager1</userId>
</User>
<User>
<userId>customManager2</userId>
</User>
<User>
<userId>customManager3</userId>
</User>
</customManager>
<proxy>
<User>
<userId>Proxy1</userId>
</User>
<User>
<userId>Proxy2</userId>
</User>
<User>
<userId>Proxy3</userId>
</User>
</proxy>
</link>
</User>
</User>
4. UPSERT in $batch
Upsert can be configured with batch processing.
Request Schema
<batchParts>
<batchChangeSet> <!--a batchChangeSet may contain multiple batchChangeSetPart -->
<batchChangeSetPart>
<method>upsert</method> <!-- The value of method must be upsert -->
<headers> <!--this is optional-->
<header>
<headerName/>
<headerValue/>
</header>
</headers>
<EntitySetName> <!--This structure is similar to upsert operation -->
<EntityTypeName>
<propertyN/>
</EntityTypeName>
<EntityTypeName>
<propertyN/>
<NavigationPropertyName1>
<NavigationEntityTypeName1>
<keyOfNavigation1>..</keyOfNavigation1>
</NavigationEntityTypeName1>
</NavigationPropertyName1>
</EntityTypeName>
</EntitySetName>
</batchChangeSetPart>
</batchChangeSet>
</batchParts>
Upsert in batch Sample
<batchParts>
<batchChangeSet>
<batchChangeSetPart>
<method>upsert</method>
<User>
<User>
<userId>CaptainMarvel</userId>
<status>active</status>
<firstName>Carol</firstName>
<lastName>Danvers</lastName>
<link>
<manager>
<User>
<userId>NO_MANAGER</userId>
</User>
</manager>
</link>
</User>
<User>
<userId>BlackPanther</userId>
<status>active</status>
<firstName>T'Challa</firstName>
<matrixManager>
<User>
<userId>NickFury</userId>
</User>
</matrixManager>
</User>
</User>
</batchChangeSetPart>
</batchChangeSet>
<batchChangeSet>
<batchChangeSetPart>
<method>upsert</method>
<User>
<User>
<status>active</status>
<userId>Hawkeye</userId>
<firstName>Clinton</firstName>
<lastName>Barton</lastName>
</User>
</User>
</batchChangeSetPart>
</batchChangeSet>
</batchParts>
Response Schema for Success
<batchPartsResponse>
<batchChangeSetReponse><!--a batchChangeSetResponse may contain multiple batchChangeSetPartResponse if success.-->
<batchChangeSetPartReponse> <!--Success ChangeSet response-->
<statusCode/>
<statusInfo/>
<contentId/>
<headers>
<header>
<headerName/>
<headerValue/>
</header>
</headers>
<body>
<UpsertResponses>
<EntitySetName>
<upsertResponseProperties>...</upsertResponseProperties>
<EntitySetName>
</UpsertResponses>
</body>
</batchChangeSetPartReponse>
</batchChangeSetReponse>
<batchChangeSetResponse> <!--Failure ChangeSet response-->
<batchChangeSetPartResponse>
<headers>
<Accept/>
<Accept-Language/>
<Content-Length>320</Content-Length>
<DataServiceVersion>1.0</DataServiceVersion>
<Content-Type>application/xml; charset=utf-8</Content-Type>
</headers>
<statusInfo>Internal Server Error</statusInfo>
<contentId/>
<body>
<error>
<code>ServerErrorException</code>
<message lang="en-US">
</message>
</error>
</body>
<statusCode>500</statusCode>
</batchChangeSetPartResponse>
</batchChangeSetResponse>
</batchPartsResponse>
Response Sample for Success and Failure
<batchPartResponse>
<batchChangeSetResponse> <!--Successs ChangeSet Response-->
<batchChangeSetPartResponse>
<headers>
<Accept/>
<Accept-Language/>
<Content-Length>581</Content-Length>
<DataServiceVersion>1.0</DataServiceVersion>
<Content-Type>application/atom+xml; charset=utf-8</Content-Type>
</headers>
<statusInfo>OK</statusInfo>
<contentId/>
<body>
<UpsertResponses>
<User>
<key>CaptainMarvel</key>
<status>OK</status>
<editStatus>UPDATED</editStatus>
<message null="true"/>
<index type="Edm.Int32">0</index>
<httpCode type="Edm.Int32">204</httpCode>
<inlineResults type="Bag(SFOData.UpsertResult)"/>
</User>
</UpsertResponses>
</body>
<statusCode>200</statusCode>
</batchChangeSetPartResponse>
</batchChangeSetResponse>
<batchChangeSetResponse> <!--Failure ChangeSet response-->
<batchChangeSetPartResponse>
<headers>
<Accept/>
<Accept-Language/>
<Content-Length>320</Content-Length>
<DataServiceVersion>1.0</DataServiceVersion>
<Content-Type>application/xml; charset=utf-8</Content-Type>
</headers>
<statusInfo>Internal Server Error</statusInfo>
<contentId/>
<body>
<error>
<code>ServerErrorException</code>
<message lang="en-US">ChangeSet index 1 - DUPLICATE_USERNAME : Failed to add/update user [Testing] "" (N/A;N/A;N/A): Duplicate Username - "Hawkeye".
</message>
</error>
</body>
<statusCode>500</statusCode>
</batchChangeSetPartResponse>
</batchChangeSetResponse>
</batchPartResponse>
It's very helpful. If CPI SF adapter receiver screenshotes or some notes are provided as well, that will be brilliant.
Thanks for your feedback Ilya. I will update the post in coming days with more information on SF OData Receiver adapter.
informative.
It will be good if Adapter can provide the option to split the batch requests into multiple requests similar to Paging Option as the batch operation can support only 180 operations.
Hi Rajesh. The adapter cannot split the incoming payload to 180 operations because there can be 'n' operations within a changeSetPart. And 'n' ChangeSetParts within a ChangeSet.
However, this can be achieved using other steps in the Iflow like a Splitter, Message mapping.
Hi Saranya, do you have a screenshot of the SF adapter?
Hi Saranya Baskaran ,
It will be very much helpful if you share the the successfactor adapater screenshot for $Batch operation. What url should we use in address field in processing tab?
Also do we need to set any header for batch operation?
Regards,
Souvik
Hi Saranya
Based on your blog, I am inspired to use it. The task I need to run is to update the email, and I am using the SF Employee Central entity PerEmail.
At the moment of running CPI, it gives me the errors and not if I have the error in the connection or something else that I should configure. It has a complete example that you can share
error -->
com.sap.gateway.core.ip.component.odata.exception.OsciException:
Request Payload Parsing Failed for one of the reason:
(1) Either the OData metadata content available in the server is outdated OR
(2) The request payload seems to be incorrect. Error Details : Entity Set batchParts not found in the edmx.
Request Payload :
Regards
Hi Luis,
From the error, I infer that you are passing a batch payload but have not configured the checkbox 'Enable Batch Processing'.
https://blogs.sap.com/2017/05/10/batch-operation-in-odata-v2-adapter-in-sap-cloud-platform-integration/
Hi Saranya,
Thank you for the great post. We are going to use UPSERT operation in $batch. But we are aware of that parameter "purgeType" need to be set like below.
In this case, which setting shall we apply in the "method" or "uri" field?
Your advice would be appreciated.
Thanks & Regards.
Hi Hu Lang,
This has to be set in the <uri> tag of the batch payload along with the function import name.
<uri>upsert?purgeType=full</uri>
Hi Saranya Baskaran
For SIMPLE UPSERT, If lets say 10 records we are Upserting at a single call. Among them 4th and 8 th records having wrong data. So while doing the all 10 records upsert, all upsert will fail or only those 2 records will fail to upsert? How the response will come?
Regards,
Souvik
Hi Saranya Baskaran
I'm looking for something like purgeType=full. I'm doing a batch upsert for Rehire but few fields carry the previous data.
Please give an example where <uri>upsert?purgeType=full</uri> should be placed exactly in the batch structure.
Below one doesnot work
<batchChangeSetPart>
<method>upsert</method>
<uri>upsert?purgeType=full</uri>
<PerPersonal>
<PerPersonal>
<personIdExternal>xxxxxxxx</personIdExternal>
<startDate>2020-08-19</startDate>
<endDate>9999-12-31</endDate>
<firstName>Count</firstName>
<lastName>Rugen</lastName>
<customString4/>
<gender>M</gender>
<nationality>CAN</nationality>
<nativePreferredLang>11298</nativePreferredLang>
<customString5>78</customString5>
</PerPersonal>
</PerPersonal>
</batchChangeSetPart>
Regards
Tarika
Hi Saranya,
I would like to do one shot update of all portlets for Hire scenarios for PerPerson,EmpEmployment,EmpJob,PerPersonal etc. and if any of portlet failed to update/upsert then it should rollback generating the error response.In Such cases what would be the format of request payload to create using below tags.Do I need to keep all entity tags in one batchChangeSetpart one after another?
Also, what we need to maintain in entity name in channel processing tab.Is it overwritten by incoming xml with batch format we send.
Regards
Deepak
Hi Deepak,
The information your looking for is about changeSet behavior i request you to refer below links which should answer your questions :-
https://www.odata.org/documentation/odata-version-2-0/batch-processing/
https://help.sap.com/viewer/d599f15995d348a1b45ba5603e2aba9b/2105/en-US/869a37d42a2849d6bc8cda597df18bd1.html
I have a problem in accessing upsert functionality of SuccessFactors from CPI. I am using Succesfactors odata v2 adapter in CPI but I am unable to find the Upsert Enitity .
I cannot find the upsert Entity in the SuccessFactors OData v2 in CPI. But I am able to access the same using Postman. Other odata functionalities are accessible from CPI using Oauth2 saml bearer token. Upsert functionality belongs to function-import operation of SuccessFactors adapter. Is it implemented in SuccessFactors adapter?
Cannot find the upsert entity in SF adapter
Postman Client
In the screenshot, I am able to access the same upsert odata in postman with the same oauth token. I am unable to find the same in CPI. Please provide the solution for this issue.
Thanks in advance.
Thanks Saranya, very helpful blog esp regarding $batch upsert!
Hi saranya , it was very helpful content , i have a requirement to upsert 200 records user id and email id in SF , how can we achieve this.