リードデータエクスポートポリシー移行の例
| 使用可能なインターフェース: Salesforce Classic および Lightning Experience |
| 使用可能なエディション: Enterprise Edition、Unlimited Edition、および Developer Edition Salesforce Shield または Salesforce Event Monitoring アドオンサブスクリプションが必要です。 |
ここまでに決定した内容をまとめます。
- 2 つの拡張ポリシーを作成する (1 つは ReportEvent に基づき、もう 1 つは ApiEvent に基づく)。
- QueriedEntities 項目と RowsProcessed 項目を使用して ReportEvent ポリシーに条件を追加する。
- QueriedEntities 項目、ElapsedTime 項目、RowsProcessed 項目を使用して ApiEvent ポリシーに条件を追加する。
- 条件ビルダーを使用してポリシーを作成すると共に、Apex コードを表示する。
以下は、移行する従来のポリシーの Apex コードです。
1global class DataLoaderLeadExportCondition implements TxnSecurity.PolicyCondition {
2 public boolean evaluate(TxnSecurity.Event e) {
3 // The event data is a Map<String, String>.
4 // We need to call the valueOf() method on appropriate data types to use them in our logic.
5 Integer numberOfRecords = Integer.valueOf(e.data.get('NumberOfRecords'));
6 Long executionTimeMillis = Long.valueOf(e.data.get('ExecutionTime'));
7 String entityName = e.data.get('EntityName');
8
9 // Trigger the policy only for an export on leads, where we are downloading
10 // more than 2000 records or it took more than 1 second (1000ms).
11 if ('Lead'.equals(entityName)){
12 if (numberOfRecords > 2000 || executionTimeMillis > 1000){
13 return true;
14 }
15 }
16
17 // For everything else don't trigger the policy.
18 return false;
19 }
20}- QueriedEntities Equals Lead
- RowsProcessed Greater than 2000

アクションページで、従来のポリシーと同じアクションを指定します。
ApiEvent ポリシーを作成する手順は似ていますが、条件ロジックを使用する点が異なります。従来のポリシーは、処理された行数が 2,000 を超えたか、経過時間が 1,000 を超えたリードのエクスポートを監視します。条件ビルダーでは、このロジックを次の方法で実装します。

これで完了です。
ApiEvent 拡張ポリシーの Apex コードは次のようになります。
1global class LeadExportApiEventCondition implements TxnSecurity.EventCondition {
2
3 public boolean evaluate(SObject event) {
4 ApiEvent apiEvent = (ApiEvent) event;
5
6 Decimal rowsProcessed = apiEvent.RowsProcessed;
7 Decimal elapsedTime = apiEvent.ElapsedTime;
8 String queriedEntities = apiEvent.QueriedEntities;
9
10 if ('Lead'.equals(queriedEntities)){
11 if (rowsProcessed > 2000 || elapsedTime > 1000) {
12 return true;
13 }
14 }
15 return false;
16 }
17}上記の例で、拡張ポリシーの Apex コードがいかに明瞭簡潔で自然かがわかります。たとえば、従来の方法では次のように処理された行数を取得します。
1Integer numberOfRecords = Integer.valueOf(e.data.get('NumberOfRecords'));次の拡張ポリシーコードでは、項目値を型キャストせずに、必要な値をイベントオブジェクトから直接取得できます。
1Decimal rowsProcessed = apiEvent.RowsProcessed;大幅に改善されて読みやすくなっています。もう一方の ReportEvent ポリシーの Apex コードは次のようになります。
1global class LeadExportReportEventCondition implements TxnSecurity.EventCondition {
2
3 public boolean evaluate(SObject event) {
4 ReportEvent reportEvent = (ReportEvent) event;
5
6 Decimal rowsProcessed = reportEvent.RowsProcessed;
7 String queriedEntities = reportEvent.QueriedEntities;
8
9 if ('Lead'.equals(queriedEntities)) {
10 if (rowsProcessed > 2000) {
11 return true;
12 }
13 }
14 return false;
15 }
16}Apex クラスの統合例
上記の新しいリードデータエクスポート拡張ポリシーの 2 つの Apex クラスが似ていることに気付きましたか? 主な違いは、一方のポリシーは sObject を ReportEvent に、もう一方は ApiEvent にキャストしていることです。この使用事例を少し変更して、複数のイベントオブジェクトを処理する 1 つの Apex クラスを作成する方法を説明します。この場合、ApiEvent の経過時間をチェックする条件を削除します。これで 2 つのポリシーがそれぞれのイベントオブジェクト RowsProcessed と QueriedEntities の同じ項目を監視するようになりました。
以下は、「統合された」 Apex クラスの例です。
1global class LeadExportEventCondition implements TxnSecurity.EventCondition {
2 public boolean evaluate(SObject event) {
3 switch on event{
4 when ApiEvent apiEvent {
5 return evaluate(apiEvent.QueriedEntities, apiEvent.RowsProcessed);
6 }
7 when ReportEvent reportEvent {
8 return evaluate(reportEvent.QueriedEntities, reportEvent.RowsProcessed);
9 }
10 when null {
11 return false;
12 }
13 when else{
14 return false;
15 }
16 }
17 }
18
19 private boolean evaluate(String queriedEntities, Decimal rowsProcessed){
20 if ('Lead'.equals(queriedEntities) && rowsProcessed > 2000){
21 return true;
22 }
23 return false;
24 }
25}上記の例は、複数のイベントオブジェクトを処理するポリシーの Apex コードが暗黙的な型キャスト、分岐ロジック、イベントエラーのケースを switch ステートメントで使用する方法を示しています。新しいイベントオブジェクトまたは使用事例を処理するようにこのコードを更新することも簡単です。
新しい使用事例を使用したリードデータエクスポートの例の拡張
たとえば、組織にリードと他のオブジェクト (キャンペーンなど) に基づいて作成したカスタムレポートタイプがあるとします。このレポートにも拡張ポリシーを適用する必要があります。この場合、QueriedEntities 項目には、Lead,Campaign,MyOtherObject など、カスタムレポートタイプが基づいているオブジェクトのカンマ区切りリストが含まれます。このカスタムレポートタイプに対して拡張ポリシーがトリガされるようにするには、equals() ではなく contains() メソッドを使用して、QueriedEntities 値に Lead があるかチェックします。次に例を示します。
1global class LeadExportEventCondition implements TxnSecurity.EventCondition {
2 public boolean evaluate(SObject event) {
3 switch on event{
4 when ApiEvent apiEvent {
5 return evaluate(apiEvent.QueriedEntities, apiEvent.RowsProcessed);
6 }
7 when ReportEvent reportEvent {
8 return evaluate(reportEvent.QueriedEntities, reportEvent.RowsProcessed);
9 }
10 when null {
11 return false;
12 }
13 when else {
14 return false;
15 }
16 }
17 }
18
19 private boolean evaluate(String queriedEntities, Decimal rowsProcessed){
20 if (queriedEntities.contains('Lead') && rowsProcessed > 2000){
21 return true;
22 }
23 return false;
24 }
25
26}次に、リードに加えてカスタムオブジェクト HRCase__c を監視するとします。条件を QueriedEntities 項目に追加します。次に例を示します。
1global class DataExportEventCondition implements TxnSecurity.EventCondition {
2 public boolean evaluate(SObject event) {
3 switch on event{
4 when ApiEvent apiEvent {
5 return evaluate(apiEvent.QueriedEntities, apiEvent.RowsProcessed);
6 }
7 when ReportEvent reportEvent {
8 return evaluate(reportEvent.QueriedEntities, reportEvent.RowsProcessed);
9 }
10 when null {
11 return false;
12 }
13 when else{
14 return false;
15 }
16 }
17 }
18
19 private boolean evaluate(String queriedEntities, Decimal rowsProcessed){
20 if (containsQueriedEntities(queriedEntities) && rowsProcessed > 2000){
21 return true;
22 }
23 return false;
24 }
25
26 private boolean containsQueriedEntities(String queriedEntities){
27 return queriedEntities.contains('Lead') ||
28 queriedEntities.contains('HRCase__c');
29 }
30}ここまで、API クエリおよびレポート操作を監視するのに、ApiEvent および ReportEvent イベントオブジェクトを使用してきました。その他に、リストビューを使用して組織データの表示やエクスポートを行うこともできます。この場合、ListViewEvent イベントオブジェクトを使用します。この Apex コードを更新するには、switch ステートメントを追加します。
1global class DataExportEventCondition implements TxnSecurity.EventCondition {
2 public boolean evaluate(SObject event) {
3 switch on event{
4 when ApiEvent apiEvent {
5 return evaluate(apiEvent.QueriedEntities, apiEvent.RowsProcessed);
6 }
7 when ReportEvent reportEvent {
8 return evaluate(reportEvent.QueriedEntities, reportEvent.RowsProcessed);
9 }
10 when ListViewEvent listViewEvent {
11 return evaluate(listViewEvent.QueriedEntities, listViewEvent.RowsProcessed);
12 }
13 when null {
14 return false;
15 }
16 when else {
17 return false;
18 }
19 }
20 }
21
22 private boolean evaluate(String queriedEntities, Decimal rowsProcessed){
23 if (containsQueriedEntities(queriedEntities) && rowsProcessed > 2000){
24 return true;
25 }
26 return false;
27 }
28
29 private boolean containsQueriedEntities(String queriedEntities){
30 return queriedEntities.contains('Lead') ||
31 queriedEntities.contains('HRCase__c');
32 }
33}