In real life, the integration is not always about creating individual records. In my experience, a lot of integration scenarios are related to transaction integrity. This means that a group of related Create, Update and Delete requests are executed as one logical transaction. Transactions are useful in scenarios where you have to commit a group of operations/requests in entirety, and ensure that the system will roll back all changes if any of the requests fail.
In general, most of the synchronous plugins, synchronous workflows and actions support transactions, but it is not recommended (best practices) to use them for integration. D365 also provides the ExecuteTransactionRequest method to support transactions. It is a part of the Organization Service (“SOAP Endpoints”). Using this means that you have to add Microsoft.Crm.Sdk.Proxy.dll and Microsoft.Xrm.Sdk.dll assemblies to your projects.
So what would you do if you are using Logic Apps as an integration layer? One solution is to use the Web APIs Batch operation. Please check the details of this command on https://msdn.microsoft.com/en-us/library/mt607719.aspx. The primary purpose of the Batch operation is to bundle multiple requests/operations into one HTTP call. The Batch operation provides changesets to support transactions.
For this blog post, I have used CRM Web API’s Batch operation to support transaction integrity.
Scenario
I am keeping the scenario very simple. An external system is calling the Logic Apps with contactid, billing address, and shipping address.The Logic App should create both the addresses linked to the contact with the contactid. If any of the requests fail, CRM should roll back all the requests. The following screenshot displays the body of the request.
In real life, the change set can contain requests to create/update/delete different kinds of records.
Solution
We have used CRM Web APIs Batch operation to achieve transaction integrity for this scenario. For this blog, I have used the Logic App created in my previous blogs.The Logic App receives the request, get the authentication token and make the batch request. If the call is successful, the Logic App terminates with the status of Succeeded, otherwise it creates an integration log record in CRM and terminates with the status of Failed.
The updated Logic App has the following steps. Steps 4 and 5 are exactly the same as my previous blog.
Step 1
It is an HTTP trigger. It is receiving the request. The payload schema has been updated based on the body of the request.Step 2
The Web API Batch operation requires a unique batch number and changeset number. This step initialises the batch number for the request. I have used Batch_guid as the format of the batch number.Step 3
This step initialises the changeset number for the request. I have used changeset_random number (100-999) as the format for the changeset number.Step 4 and Step 5
These steps are exactly the same as my previous blog Calling D365 APIs from Logic Apps. These steps get the authentication token and parse the token so it can be used to make the Web API call.Step 6
This is the most important step. It is using a HTTP action.The request body is quite big for a batch request. The screen is just displaying the start of the body and the first request to create the customer address. To make the batch request, the following information is required.
- Use Post as Method.
- Provide the D365 Web API Uri. The last part of the Uri is the name $batch .
- Headers are the same for all the Web API calls except content-type. The content-type for the request is multipart/mixed boundary =BatchNo
- The body of the request contains all the individual calls. There are specifics on how to use batch no. and change set no. in the request. Be mindful of that. I have provided the whole app definition at the end of this blog.
Step 7
One of the reasons to create an error log is that the output of the batch request is the base64 format. The error messages are not in human-readable form. When we log them, the Logic App automatically decodes the base64 strings.
Note: I am logging the whole output body in this step. In real life, you can use the substring function to log just the error description part of it.
Step 8
The purpose of this step is to terminate the Logic App with the status Failed. Steps 7 and 8 will be executed only if Step 6 fails.Results
I have used Postman to trigger the Logic App.Successful Execution
If the call is successful, you will be able to see 2 addresses related to the contactid provided in the request body.Failed Execution
To test the failure scenario and transaction integrity, I manually updated the addresstypecode to 8 for the second request in the changeset. This addresstypecode does not exist in the CRM. The Logic App logged the following error in CRM, and there were no address records in the system. The error was in the second request, but the system has rolled back the creation of the first record too. That is how you implement transaction integrity.Where From Here
This was a simple example, but what if we had to create a Contact record first and then create Addresses linked to the Contact record created as a part of the transaction?Please share your solution in the comment section. I have a few things in my head, which we will talk about it in the next post.