Skip to Content

SAP SuccessFactors(SFSF) OData service supports a custom OData function import called UPSERT. The UPSERT operation takes care of creating or updating the records so that you do not have to do this explicitly. The UPSERT operation also allows sending of one or multiple records at the same time.

This blog will help you  to configure the receiver communication channel with Process Integration SFSF adapter, using OData Message Protocol, and run a scenario for operation Upsert.

Prerequisites

  • You have installed the latest version of SAP Process Integration, connectivity add-on 1.0 SP 03 (or at least SP02). You have to ensure you have the latest patch levels of PIADAPTERS and PICOASUF SCAs.
  • You have logged on to the Integration Builder and created a business component with the communication channel.
  • You have created the Integration Flow.
  • You have created a sender communication channel (e.g. SOAP, Axis or other).

Configuring SFSF Receiver Communication Channel for Operation Upsert

1.     Open the channel configuration.

  1. Select SFSF in the Adapter Type field.
  2. In the Transport Protocol field, select HTTP.
  3. In the Message Protocol field, select oData.
  4. In the General tab page, select the endpoint URL of the corresponding SuccessFactors system.
  5. Fill all necessary login information under Login Credentials section.
  6. If you want to use HTTP proxy to connect to the SuccessFactors system, fill the proxy settings section.

The channel configuration should be similar to the one below:

2. Navigate to the Processing tab.

2.1. Select Upsert operation in the channel configuration of the SuccessFactors Adapter.

2.2.  In the resource path write the Function Import name available in the service metadata.

According to the OData API documentation, the correct HTTP URL for Upsert request should end with the corresponding function import name. The common function import name is ‘upsert’, so you should enter the ‘upsert’ function import name in the resource path.

2.3. The payload format should be Atom or JSON depending on the needs of your scenario.

Run the SuccessFactors Scenario for Operation UPSERT

The request payload in our scenario contains information about the entity name User.  In this particular scenario, we will send request, which contains 10 tags using the SoapUI tool.

According to the OData Service metadata, the result message should be a collection of all response messages that correspond to the sent request tags, e.g.:

<FunctionImport Name=”upsert” EntitySet=”UpsertResult” sap:support-payload=”true” m:HttpMethod=”POST” ReturnType=”Collection(SFOData.UpsertResult)”/>

The request and response messages for this particular scenario are the following:

The request message:

<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:axis=”http://sap.com/test/axis”>
<soapenv:Header/>
<soapenv:Body>
<User xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”UserEntityPOST3.xsd”>
<User>
<userId>us1</userId>
<username>us1</username>
<status>active</status>
</User>
<User>
<userId>us2</userId>
<username>us2</username>
<status>active</status>
</User>
<User>
<userId>us3</userId>
<username>us3</username>
<status>active</status>
</User>
<User>
<userId>us4</userId>
<username>us4</username>
<status>active</status>
</User>
<User>
<userId>us5</userId>
<username>us5</username>
<status>active</status>
</User>
<User>
<userId>us6</userId>
<username>us6</username>
<status>active</status>
</User>
<User>
<userId>us7</userId>
<username>us7</username>
<status>active</status>
</User>
<User>
<userId>us8</userId>
<username>us8</username>
<status>active</status>
</User>
<User>
<userId>us9</userId>
<username>us9</username>
<status>active</status>
</User>
<User>
<userId>us10</userId>
<username>us10</username>
<status>active</status>
</User>
</User>
</soapenv:Body>
</soapenv:Envelope>

The response message:

<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”>
<soapenv:Body>
<SynchronousResponse xmlns=”http://sap.com/xi/XI/OData” xmlns:ns1=”http://sap.com/xi/XI/OData”>
<Result>
<StatusCode>200</StatusCode>
<StatusText>OK</StatusText>
<Message><![CDATA[<?xml version=”1.0″ encoding=”utf-8″?><feed xmlns=”http://www.w3.org/2005/Atom” xmlns:m=”http://schemas.microsoft.com/ado/2007/08/dataservices/metadata” xmlns:d=”http://schemas.microsoft.com/ado/2007/08/dataservices”><entry><content type=”application/xml”><m:properties><d:key>us1</d:key><d:status>OK</d:status><d:editStatus>UPDATED</d:editStatus><d:message m:null=”true”></d:message><d:index m:type=”Edm.Int32″>0</d:index><d:httpCode m:type=”Edm.Int32″>204</d:httpCode><d:inlineResults m:type=”Bag(SFOData.UpsertResult)”></d:inlineResults></m:properties></content></entry><entry><content type=”application/xml”><m:properties><d:key>us2</d:key><d:status>OK</d:status><d:editStatus>UPDATED</d:editStatus><d:message m:null=”true”></d:message><d:index m:type=”Edm.Int32″>1</d:index><d:httpCode m:type=”Edm.Int32″>204</d:httpCode><d:inlineResults m:type=”Bag(SFOData.UpsertResult)”></d:inlineResults></m:properties></content></entry><entry><content type=”application/xml”><m:properties><d:key>us3</d:key><d:status>OK</d:status><d:editStatus>UPDATED</d:editStatus><d:message m:null=”true”></d:message><d:index m:type=”Edm.Int32″>2</d:index><d:httpCode m:type=”Edm.Int32″>204</d:httpCode><d:inlineResults m:type=”Bag(SFOData.UpsertResult)”></d:inlineResults></m:properties></content></entry><entry><content type=”application/xml”><m:properties><d:key>us4</d:key><d:status>OK</d:status><d:editStatus>UPDATED</d:editStatus><d:message m:null=”true”></d:message><d:index m:type=”Edm.Int32″>3</d:index><d:httpCode m:type=”Edm.Int32″>204</d:httpCode><d:inlineResults m:type=”Bag(SFOData.UpsertResult)”></d:inlineResults></m:properties></content></entry><entry><content type=”application/xml”><m:properties><d:key>us5</d:key><d:status>OK</d:status><d:editStatus>UPDATED</d:editStatus><d:message m:null=”true”></d:message><d:index m:type=”Edm.Int32″>4</d:index><d:httpCode m:type=”Edm.Int32″>204</d:httpCode><d:inlineResults m:type=”Bag(SFOData.UpsertResult)”></d:inlineResults></m:properties></content></entry><entry><content type=”application/xml”><m:properties><d:key>us6</d:key><d:status>OK</d:status><d:editStatus>UPDATED</d:editStatus><d:message m:null=”true”></d:message><d:index m:type=”Edm.Int32″>5</d:index><d:httpCode m:type=”Edm.Int32″>204</d:httpCode><d:inlineResults m:type=”Bag(SFOData.UpsertResult)”></d:inlineResults></m:properties></content></entry><entry><content type=”application/xml”><m:properties><d:key>us7</d:key><d:status>OK</d:status><d:editStatus>UPDATED</d:editStatus><d:message m:null=”true”></d:message><d:index m:type=”Edm.Int32″>6</d:index><d:httpCode m:type=”Edm.Int32″>204</d:httpCode><d:inlineResults m:type=”Bag(SFOData.UpsertResult)”></d:inlineResults></m:properties></content></entry><entry><content type=”application/xml”><m:properties><d:key>us8</d:key><d:status>OK</d:status><d:editStatus>UPDATED</d:editStatus><d:message m:null=”true”></d:message><d:index m:type=”Edm.Int32″>7</d:index><d:httpCode m:type=”Edm.Int32″>204</d:httpCode><d:inlineResults m:type=”Bag(SFOData.UpsertResult)”></d:inlineResults></m:properties></content></entry><entry><content type=”application/xml”><m:properties><d:key>us9</d:key><d:status>OK</d:status><d:editStatus>UPDATED</d:editStatus><d:message m:null=”true”></d:message><d:index m:type=”Edm.Int32″>8</d:index><d:httpCode m:type=”Edm.Int32″>204</d:httpCode><d:inlineResults m:type=”Bag(SFOData.UpsertResult)”></d:inlineResults></m:properties></content></entry><entry><content type=”application/xml”><m:properties><d:key>us10</d:key><d:status>OK</d:status><d:editStatus>UPDATED</d:editStatus><d:message m:null=”true”></d:message><d:index m:type=”Edm.Int32″>9</d:index><d:httpCode m:type=”Edm.Int32″>204</d:httpCode><d:inlineResults m:type=”Bag(SFOData.UpsertResult)”></d:inlineResults></m:properties></content></entry></feed>]]></Message>
</Result>
</SynchronousResponse>
</soapenv:Body>
</soapenv:Envelope>

Troubleshooting

Note the following exceptions when using the UPSERT operation:

a.  In SuccessFactors Adapter, Function Import operation was previously available only for upsert  Function Import name. Now it is possible to have both Upsert and Function Import (GET) operations available in the OData Service Metadata. For this purpose the configuration of the operation type should remain ‘UPSERT’. Only the resource path should be modified with some particular function import name available in the Service Metadata, е.g.:

<FunctionImport Name=”getUserRolesByUserId” EntitySet=”RBPRole” sap:support-payload=”false” m:HttpMethod=”GET” ReturnType=”Collection(SFOData.RBPRole)”>

<Parameter Name=”userId” Type=”Edm.String”/>

</FunctionImport>

–  There is a possibility for adding additional parameters to the function import name in oDataResourcePath. The parameter name should be described in the service metadata:

This new feature is introduced with SAP Note 2330138.

b. Upserting multiple records in one request (i.e. batch upsert operation) is not supported by SuccessFactors APIs for some particular entities such as SFOData.Background_OutsideWorkExperience, SFOData.Background_InsideWorkExperience, Background_Education and others. For example if the following request is sent:

As a result the following error message appears:

For more details , you can refer to KBA 2327402 – Error message: “COE_UNSUPPORTED_FEATURE – Unsupported feature: batch upsert”.

There is a solution for this issue from Process Integration side. With SAP Note 2572963  a new property ‘SplitPayload’ is introduced in the SuccessFactors Receiver channel in OData mode, which can be configured in the table for additional parameters of the Advanced tab:

When the SplitPayload property value is set to “true” the payload will be split into single records. The result message should not be a collection of multiple messages (as shown in point 2). Instead, it will be split into multiple response tags similar to the following:

c. If you are on older patch level and you upgrade to the latest patch level, the following error might be displayed:

 java.lang.NullPointerException: while trying to invoke the method         org.apache.olingo.odata2.api.edm.EdmFunctionImport.getHttpMethod() of a null object returned from org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo.getFunctionImport()

The previous implementation of the Upsert operation was based on a Create Entity operation call. Therefore , the single entity name was configured in the Resource path instead of a function import name, which was not the correct behavior, e.g:

The performance of the old implementation was not so good, because the create Entity call could send a single record at a time but we need a bulk message to be processed. The Upsert operation is now correctly implemented and it should be configured as shown in the screenshot from point 2. The configuration in OData Resource Path is now modified to expect a particular function import name instead of a single entity name.

This solution is introduced with SAP Note 2330138.

 

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply