LinkedIn

Salesforce Change Data Capture - Asynchronous Triggers and Subscription using MuleSoft & CometD

 In this post, let us see what is Change Data Capture, when to use them and the different subscription approaches.

1. What is Change Data Capture

Change Data Capture is similar to Platform Events. This can be used to keep your external system in sync with Salesforce data. It is supported for all custom Objects and some standard Objects. 

The supported standard object list can be found here.

Once enabled for a particular object, whenever that object record is created, updated, deleted or undeleted, an event will be fired to the event bus. This fired event will be available for 72 hours on the bus and an external application can subscribe to this.

How it is different from Platform events?

1. In platform events, we can define our own fields and structure whereas CDC is applied on existing Objects

2. You can publish platform events from Flows, Apex, and process but CDC is fired by default on record changes

How to Enable CDC?

Go to setup->Integrations->Change Data Capture

Here you can select Objects. Please note, by default you can select only 5 objects. If we need to capture more objects we need to purchase an additional license.


2. CDC Event Structure

The CDC Object is always called <Objectname>ChangeEvent

Example - AccountChangeEvent, ContactChangeEvent,customObject__cChangeEvent

Below is the structure of CDC event:


Header Field Details:


Body Field Details:


3. Subscribe using Trigger

One of the advantage of CDC is that, you can create an after Insert Trigger on ChangeEvent record. 

Advantage of this approach:



Use Case:

When ever a new contact is getting created/updated with Country field value, parent Account's Account country field should be appended with new country

If Account ABC has 2 contact - Contact X with country India and Contact Y with country France, the Account Country in Account ABC should be updated as India,France

Solution Approach using CDC:

1. Enable CDC on Contact

We have done this already.

2. Create Trigger on ContactChangeEvent to process Data

Trigger Logic:

Note- below code is not containing complete logic and not following trigger handler best practice.

trigger contacteventTrigger on ContactChangeEvent (after insert) {
System.debug('CPU time1:'+Limits.getCpuTime());
Set<id> accIds = new Set<id>();
for(ContactChangeEvent ce : Trigger.new){
System.debug(ce);
System.debug(ce.AccountId);
EventBus.ChangeEventHeader header = ce.ChangeEventHeader;
if(header.changetype == 'CREATE'){
if(ce.country__c != null){
accIds.add(ce.AccountId);
}
}
}
if(accIds.size()>0){
//Query and get All contacts
Map<id,String> accidtoContactsMap = new Map<id,String>();
for(Contact con : [Select id, Country__c,accountID from Contact where accountid IN :accIds] ) {
if(accidtoContactsMap.get(con.accountid) != null && !accidtoContactsMap.get(con.accountid).contains(con.Country__c)){
String cntry = accidtoContactsMap.get(con.accountid)+','+con.Country__c;
System.debug('cntry:'+cntry);
accidtoContactsMap.remove(con.accountid);
accidtoContactsMap.put(con.accountid,cntry);
System.debug('accidtoContactsMapinside loop if:'+accidtoContactsMap);
}
else if(accidtoContactsMap.get(con.accountid) == null){
accidtoContactsMap.put(con.accountID, con.Country__c);
System.debug('accidtoContactsMapinside loop else:'+accidtoContactsMap);
}
}
System.debug('accidtoContactsMap:'+accidtoContactsMap);
//Create list of accounts to be updated
List<Account> acctoupd = new List<Account>();
for(Id accid : accidtoContactsMap.keyset()){
acctoupd.add(new Account(id=accid, Account_Country__c =accidtoContactsMap.get(accid)) );
}
if(acctoupd.size()>0){
update acctoupd;
}
}
System.debug('CPU time2:'+Limits.getCpuTime());
}

You can see that Trigger is on ContactChangeEvent and the operation is always after Insert

To enable debug log for Asynchronous trigger, we need to enable it on Automated Process as hsown below:


Account Record:


You can see Account country is empty.

Now let us insert a new contact - Contact X with country as India.



You can see Account Coutry got updated as India now:


In the debug you can see an entry for automated process:



The record on ContactChangeEvent looks like below:



4. Subscribe using CometD Client

This blog details how you can subscribe to events using CometD Client. Using that approach, I subscribed to ContactChangeEvent, and you can see events getting subscribed in CometD Client:

Subscibe using below command:

 java -classpath target/emp-connector-0.0.1-SNAPSHOT-phat.jar com.salesforce.emp.connector.example.LoginExample <username> <password+securitytoken> /data/ContactChangeEvent

When w execute this, you can see events are getting subscribed, which got published in the last 72 hours:


5. Subscibing from Mulesoft Anypoint Platform

Subscribing to CDC events from Mulesoft Anypoint platform is easy. You can use a 30 day trial version. 

1. Install Anypoint Studio from here

2. Once installation completed, run AnypointStudio.exe :

3. Create a new Mule project



4. Install Salesforce connector - Mule 4 from Exchange. Follow this link




5. Add a global Configuration element for Salesoforce connection. I used Basic authentication.




6. Add a Replay channel from the Mule Palatte->Salesforce Connector




7. Update the properties as shown below:



8. Add a Logger Compoenent also to see payload Info in console



9. Run the project by right clicking and selecting Run project




10. In salesforce, create a new Contact and check Anypoint Studio console:



11. We will be able to update Repaly options to define subscribe approach.



Now you will be able to add additinal logic in AnypointStudio to transform the received payload and load it to any oter system


6. Considerations


CDC will not be generated for below changes:



Concurrent Client Allocation


Default Allocation Details


References:

https://developer.salesforce.com/docs/atlas.en-us.change_data_capture.meta/change_data_capture/cdc_when_to_use.htm 

https://help.mulesoft.com/s/article/How-to-Subscribe-to-Salesforce-Change-Data-Capture-with-Mule-4

https://docs.mulesoft.com/salesforce-connector/0.3.8/

Comments

Post a Comment

Popular posts from this blog

Subscribing to Salesforce Platform Events using External Java Client - CometD

Send Data from Salesforce to Data Cloud using Ingestion API and Flow

How to develop reusable Invocable Apex methods for Flows