At one of our customers we wanted to implement the Exactly Once In Order mechanism. By default, this function is not available in SAP Cloud Platform Integration. There’s already a Exactly Once mechanism available. This is also not a standard function. But a colleague made a blog how you can set up Exactly Once mechanism in SAP Cloud Platform Integration. See below for the link to the blog. This mechanism however did not fulfill the requirements of the customer.
Our starting point is a standard content interface Replicate Sales Order. SAP ECC can send new Sales Orders and Sales Order updates. If a Sales Order update message can’t be delivered to the receiver. The message will be stored in the datastore. The ‘exactly once’ mechanism has a timer start event. Every 60 minutes SAP Cloud Platform Integration will pick up the messages from the datastore. In the meantime, there potentially could be another Sales Order update message for the same Sales Order. If this message is successfully delivered the first time, we will still have the previous older Sales Order update in the datastore. With the ’exactly once‘ mechanism, this older datastore message will be sent to C4C and so an old Sales Order update message will be executed in SAP C4C and will overwrite the newer one.
Exactly Once with Sequencing.
We used the ‘exactly once’ mechanism and added some functions to make it work as “exactly once in order”. Our custom version is not completely the same. Because we aren’t delivering every message in the same order as we receive the messages. Our version only sends the latest message and deletes the old messages. Below we will explain in detail how our version works.
Store Latest DateTimeStamp
For every message we receive in SAP Cloud Platform Integration we are storing the current DateTimeStamp with SalesOrderID as entry ID. In this example the field SenderSequenceNumberValue contains the current date and time. In case the current DateTimeStamp is not available in the message, you can define your own DateTimeStamp in a property, using an expression.
In the write pattern use the SalesOrderID as entryID. So for each SalesOrder the latest timestamp will be stored in the datastore.
Don’t forget to check the ‘Overwrite Existing Message’ option.
Compare Retry DateTimeStamp
The second main integration flow starts with a timer. This process will pick up the retry messages from the data store. A general splitter will split the messages. For each message we are storing the SalesOrderID, retry DateTimeStamp and the retry message body in a variable.
After storing we will do a “GET” operation with SalesOrderID as entry ID to pick up the latest DateTimeStamp. You also need to store this in a variable and put the retry message in the body. See pictures below.
Now we can compare the latest DateTimeStamp with the retry DateTimeStamp of the SalesOrder. For this we will use the router with below Condition Expression.
Check latest DateTimeStamp with the DateTimeStamp from the retry message. If the retry DateTimeStamp is greater than the latest DateTimeStamp, then the message in the data store is the newest and the iFlow will then continue to send the message to the receiver. If the retry DateTimeStamp is smaller than the latest DateTimeStamp, the message in the data store will not be sent to the receiver and will be deleted from the datastore.
This only works for sending complete messages. It will not work if a part of a message is sent.
Salim Dahchour and Rik Dingemans