salesforce零基礎學習(一百零五)Change Data Capture
- 2021 年 7 月 11 日
- 筆記
- integration, salesforce&apex, salesforce學習
本篇參考:
//trailhead.salesforce.com/content/learn/modules/change-data-capture
//developer.salesforce.com/blogs/2018/08/what-is-change-data-capture.html
salesforce零基礎學習(九十六)Platform Event淺談
salesforce零基礎學習(八十五)streaming api 簡單使用(接近實時獲取你需要跟蹤的數據的更新消息狀態)
我們在前面介紹過 Push Topic 以及 Platform Event這兩個 Streaming API,可以想像未來的某天肯定還會補上一篇 Change Data Capture(CDC) 集齊 Streaming API 三件套,今天這篇博客就是對CDC進行淺入淺出。
一. CDC 概念以及什麼時候使用
提起CDC以前,還是需要先重新說一下 Streaming Event 以及 Push technology。 Streaming Event(流事件)是一個系統(發佈者)向另一個系統(訂閱者)發送的即時通知消息。使用推送技術,發佈者將數據推送到訂閱者,這個操作近乎實時。對Streaming API感興趣或者不了解的,可以查看上文的第一個鏈接。Streaming Event在salesforce中主要有三種封裝好的feature: Push Topic & Platform Event & Change Data Capture.
所以什麼場景下我們推薦使用 Change Data Capture呢?使用CDC有哪些優勢,什麼場景不建議呢?
- 使外部系統與Salesforce數據保持同步;
- 接收Salesforce記錄更改的通知,包括創建、更新、刪除和取消刪除操作;
- 可以通過CometD或者Apex Trigger去訂閱;
- 捕獲所有記錄的字段變更;
- 無論共享規則如何,訂閱者都可以廣泛訪問所有數據;
- 訂閱者基於Field Level Security,僅傳遞用戶有權訪問的字段;
- 加密 change event字段;
- 在事件的header中獲取有關更改的信息,例如更改的來源等,它可以讓訂閱方更靈活的判斷操作數據;
- 使用事務邊界執行數據更新;
- 使用版本化的事件架構;
- 以可擴展的方式訂閱大量更改;
- 訪問保留的事件最多三天。
以下場景不適用於使用CDC。
- 根據記錄和字段更改執行審核跟蹤。
- 更改數據捕獲旨在保持下游系統的同步,而不是單個用戶。如果許多用戶訂閱了CometD客戶機,那麼並發客戶機限制可能會達到。
二. CDC的發佈,結構以及訂閱
既然我們知道哪些場景推薦使用,那麼我們應該清楚如何去發佈,以及發送出去的結構和限制等細節知識,用來做一些評估和下游系統的對接。
發佈篇:
setup-> change data capture 然後選擇我們需要追蹤的表即可。這裡我們選擇了 Account以及 Opportunity,則Account 以及 Opportunity有CUD情況,下游訂閱端便可以獲取到消息數據。
結構篇:
那下游端訂閱需要了解一下CDC推送過去的格式是什麼樣,否則他們也沒法去進行解析操作,所以我們來看一下CDC推送的消息數據的格式。
通過下圖我們看到一個CDC的消息數據結構可以簡單的分成兩部分: header & body。 header用來記錄推送的表的信息,比如表名,操作的類型(CUD/UnDelete),操作的表的ID信息等等。body部分即為改動的字段的信息的鍵值隊。針對新增場景,發送所有的非空的字段以及系統字段;針對更新場景,發送所有改變了的字段;針對刪除場景,不會有任何的字段。細節可以查看一下官方的API文檔。
這裡來做一個引申,如果系統中有formula字段,在新增或者更新場景並不會發送過去,所以針對 formula字段,如果使用了CDC需要考慮進行單獨的處理,如果前期未識別,後續會增加很多effort來對應。現在看上面這個截圖可能有點懵,等會通過trigger訂閱打印出來以後可以更好的了解報文內容。
訂閱篇:
salesforce針對CDC支持兩種訂閱方式: CometD以及Apex Trigger,針對 CometD不做介紹,PushTopic & Platform Event & CDC都是支持CometD訂閱方式,如果涉及到下游系統,直接根據官方文檔中的demo一步一步配置,很輕鬆的就可以實現。這裡主要是介紹一下 Apex Trigger方式訂閱。
要知道,如果我們使用 PushTopic方式訂閱,如果下游系統真的沒收到數據是一個很麻煩的事情,我們沒法去和他們解釋到底是salesforce沒有廣播這條數據,還是訂閱端問題,會有適當的扯皮操作,但是使用CDC我們完全不會有這個疑問,因為當廣播出去以後,我們可以通過trigger去實現訂閱從而實現tracking。不是所有的表都支持CDC,所以我們可以去查看一下官方文檔來確定一下。針對支持的表,trigger的寫法和 ApexTrigger很相似,區別就是監控的表為 [Object]ChangeEvent。如果是標註你的表,則直接使用名稱,比如 AccountChangeEvent。如果是自定義表,則中間需要加上兩個下劃線,比如 CustomObject__ChangeEvent。並且只允許 after insert使用。下面的例子是針對 OpportunityChangeEvent進行監聽,如果是Stage為Close Won情況下,創建一個Task。通過這個trigger,我們也可以打印出來實際的這個結構。
trigger OpportunityChangeTrigger on OpportunityChangeEvent (after insert) { List<Task> tasks = new List<Task>(); // Iterate through each event message. for (OpportunityChangeEvent event : Trigger.New) { // Get some event header fields EventBus.ChangeEventHeader header = event.ChangeEventHeader; system.debug('event : ' + JSON.serialize(event)); if (header.changetype == 'UPDATE') { System.debug('List of all changed fields:'); for (String field : header.changedFields) { if (null == event.get(field)) { System.debug('Deleted field value (set to null): ' + field); } else { System.debug('Changed field value: ' + field + '. New Value: ' + event.get(field)); } } } if ((header.changetype=='UPDATE') && (event.isWon==true)) { // Create a task Task tk = new Task(); tk.Subject = 'Follow up on won opportunities: ' + header.recordIds; tk.OwnerId = header.CommitUser; tasks.add(tk); } } // Insert all tasks in bulk. if (tasks.size() > 0) { insert tasks; } }
需要知道的是,如果我們希望在debug log中查看到CDC相關的訂閱信息,需要將 Traced Entity Type設置成 Automated Process。
我們新建一條 Opportunity的情況下,以下是創建的內容。
可以看一下message 的結構,其中包括了當前的類型,以及變更的字段以及其字段對應的值,通過header我們可以看到這條記錄執行的是CREATE的操作。不是所有的字段都展示在這裡,只有內容非空的才會在body中。
{ "IsClosed": false, "attributes": { "url": "/services/data/v52.0/sobjects/OpportunityChangeEvent/4881111", "type": "OpportunityChangeEvent" }, "IsWon": false, "IsSplit": false, "CloseDate": "2021-07-10", "ReplayId": "4881111", "ForecastCategory": "Pipeline", "Name": "測試CDC 0710", "IsExcludedFromTerritory2Filter": false, "Probability": 10, "OwnerId": "0053g000000lqx1AAA", "LastModifiedDate": "2021-07-10T15:58:07.000+0000", "Id": "1CExx000000KTnbGAG", "HasOpportunityLineItem": false, "StageName": "Prospecting", "IsPrivate": false, "ForecastCategoryName": "Pipeline", "LastModifiedById": "0053g000000lqx1AAA", "CreatedById": "0053g000000lqx1AAA", "ChangeEventHeader": { "recordIds": [ "0063g00000AQHUwAAP" ], "nulledFields": [], "diffFields": [], "commitUser": "0053g000000lqx1AAA", "entityName": "Opportunity", "changeType": "CREATE", "commitNumber": 11077894054001, "changedFields": [], "commitTimestamp": 1625932687000, "changeOrigin": "com/salesforce/api/soap/52.0;client=SfdcInternalAPI/", "transactionKey": "00038c39-bc36-b76b-776e-d489f264045f", "sequenceNumber": 1 }, "CreatedDate": "2021-07-10T15:58:07.000+0000" }
將這條數據進行update操作,設置amount,並且修改一下Stage Name
我們可以看一下message詳情架構如下:body中擁有了 Amount信息以及修改的字段的信息。我們可以看到現在的change Type是 UPDATE。在header的changedFields區域就可以看到這次修改的哪些字段。
{ "IsClosed": false, "attributes": { "url": "/services/data/v52.0/sobjects/OpportunityChangeEvent/4890418", "type": "OpportunityChangeEvent" }, "Amount": 101.0, "LastModifiedDate": "2021-07-11T05:40:20.000+0000", "IsSplit": false, "HasOpportunityLineItem": false, "LastAmountChangedHistoryId": "0083g00000KllvXAAR", "IsExcludedFromTerritory2Filter": false, "Id": "1CExx000000KWDiGAO", "ReplayId": "4890418", "StageName": "Needs Analysis", "IsPrivate": false, "LastStageChangeDate": "2021-07-11T05:40:20.000+0000", "IsWon": false, "ChangeEventHeader": { "recordIds": [ "0063g00000AQHUwAAP" ], "nulledFields": [], "diffFields": [], "commitUser": "0053g000000lqx1AAA", "entityName": "Opportunity", "changeType": "UPDATE", "commitNumber": 11078205948865, "changedFields": [ "StageName", "Amount", "ExpectedRevenue", "LastModifiedDate", "LastStageChangeDate", "LastAmountChangedHistoryId" ], "commitTimestamp": 1625982020000, "changeOrigin": "com/salesforce/api/soap/52.0;client=SfdcInternalAPI/", "transactionKey": "0003bba5-8a9b-2ad2-c3c3-a15a295b2bb5", "sequenceNumber": 1 }, "ExpectedRevenue": 20.2 }
三. CDC 、 PushTopic、Platform Event 區別
我們作為開發人員還好,可能架構選型以後,我們了解做了就好。但是哪天我們做到了架構,需要我們選型相關的,我們如何去選型呢?這三個有什麼區別或者優缺點,如何去取捨?下圖是我們官方的一個比較,詳情鏈接://developer.salesforce.com/docs/atlas.en-us.232.0.api_streaming.meta/api_streaming/event_comparison.htm?search_text=Platform%20Event
除了這種 high level的比較,一定要確定好選型以後的細節考慮。比如 PushTopic的query的長度限制,Change Data Capture formula字段變更不會傳過去,而且超過指定的數量需要花錢等等。high level決定選型,細節決定了你的effort,缺一不可。
總結:篇中淺入淺出介紹了一下CDC的使用,至此streaming api 廣播訂閱的三個模型都已經有簡單介紹。很多細節介紹也沒有展開,比如trigger一次進入數據的數據量必須2000以內等等。如果用到了這個模型,詳細查看官方文檔進行夯實即可。篇中有錯誤歡迎指出,有不懂歡迎留言。