-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathEnqueueNextQueueableProcessStep.cls
More file actions
117 lines (110 loc) · 4.46 KB
/
Copy pathEnqueueNextQueueableProcessStep.cls
File metadata and controls
117 lines (110 loc) · 4.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**
* @description This class implements the Apex Transaction Finalizer interface. It's used to implement promises. This
* class is constructed with a list of QueueableProcess Objects, and any passthrough data. The first promise in the list
* is executed. The QueueableProcess class automatically attaches this finalizer to it's execution.
*/
public with sharing class EnqueueNextQueueableProcessStep implements System.Finalizer {
/**
* @description a DataProvider instance. This is used to allow for dependency injection in unit tests.
*/
@TestVisible
QueueableProcessDataProvider dataProvider = new QueueableProcessDataProvider();
/**
* @description A list of QueueableProcess Objects. The first step in the list is executed.
*/
private final List<QueueableProcess> processSteps;
/**
* @description This field allows you to pass information into your initial QueueableProcessStep. This is also the
* field that is passed to the next QueueableProcessStep in the list.
*/
private final Object dataPassthrough;
private final List<QueueableContext> queueableContextHistory;
private List<FinalizerContext> finalizerContextHistory;
/**
* @description Constructor for the EnqueueNextQueueableProcessStep class.
*
* @param processSteps List<QueueableProcess> A list of QueueableProcess Objects. The first step in the list is
*
* executed.
* @param dataPassthrough Object this is either the initial data passed into the first QueueableProcessStep, or the
* data passed from the previous QueueableProcessStep.
* @param queueableContextHistory List<QueueableContext> A list of QueueableContext Objects.
* @param finalizerContextHistory List<FinalizerContext> A list of FinalizerContext Objects.
*/
@SuppressWarnings('PMD.ExcessiveParameterList')
public EnqueueNextQueueableProcessStep(
List<QueueableProcess> processSteps,
Object dataPassthrough,
List<QueueableContext> queueableContextHistory,
List<FinalizerContext> finalizerContextHistory
) {
this.processSteps = processSteps;
this.dataPassthrough = dataPassthrough;
this.queueableContextHistory = queueableContextHistory;
this.finalizerContextHistory = finalizerContextHistory;
}
/**
* @description This method is required by the Apex Transaction Finalizer interface. It's used to enqueue the next
* QueueableProcessStep in the list, if one exists.
*
* @param context FinalizerContext Dependency injected by Salesforce at execution time. Contains the result of the
* QueueableProcessStep that just executed.
*/
public void execute(FinalizerContext context) {
if (this.finalizerContextHistory == null) {
this.finalizerContextHistory = new List<FinalizerContext>();
}
this.finalizerContextHistory.add(context);
if (this.finalizerContextHistory == null) {
this.finalizerContextHistory = new List<FinalizerContext>();
}
this.finalizerContextHistory.add(context);
switch on context.getResult() {
when SUCCESS {
if (this.processSteps.size() > 0) {
// Remove the first element from the list - this was constructed using the .then() method.
QueueableProcess nextProcessStep = this.processSteps.remove(0);
// Set the remaining steps on the next process step.
nextProcessStep.processSteps = this.processSteps;
// Set the dataPassthrough on the next process step.
nextProcessStep.dataPassthrough = dataPassthrough;
// Set the queueableContextHistory on the next process step.
nextProcessStep.queueableContextHistory = this.queueableContextHistory;
// Set the finalizerContextHistory on the next process step.
nextProcessStep.finalizerContextHistory = this.finalizerContextHistory;
// Enqueue the next process step.
System.enqueueJob(nextProcessStep);
}
}
when UNHANDLED_EXCEPTION {
this.handleException(context);
}
}
}
private void handleException(FinalizerContext context) {
try {
String className = this.dataProvider.getClassName(
context.getAsyncApexJobId()
);
QueueableProcess parentQueueable = (QueueableProcess) Type.forName(
className
)
?.newInstance();
parentQueueable.handleException(context.getException());
} catch (QueryException qe) {
Callable exceptionHandler = (Callable) Type.forName(
'FailsafeExceptionHandler'
)
.newInstance();
List<Exception> exceptions = new List<Exception>{
qe,
context.getException()
};
exceptionHandler
?.call(
'handleExceptions',
new Map<String, List<Exception>>{ 'incomingExceptions' => exceptions }
);
}
}
}