@izara_project/izara-core-library-asynchronous-flow 1.0.35 → 1.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +8 -87
- package/package.json +1 -1
- package/src/asyncFlowSharedLib.js +51 -100
- package/src/awaitingMultipleSteps.js +253 -713
- package/src/awaitingStep.js +57 -212
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright (C) 2021 Sven Mason <http://izara.io>
|
|
1
|
+
/* Copyright (C) 2021 Sven Mason <http://izara.io>
|
|
3
2
|
|
|
4
3
|
This program is free software: you can redistribute it and/or modify
|
|
5
4
|
it under the terms of the GNU Affero General Public License as
|
|
@@ -8,11 +7,11 @@ License, or (at your option) any later version.
|
|
|
8
7
|
|
|
9
8
|
This program is distributed in the hope that it will be useful,
|
|
10
9
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
10
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
11
|
GNU Affero General Public License for more details.
|
|
13
12
|
|
|
14
13
|
You should have received a copy of the GNU Affero General Public License
|
|
15
|
-
along with this program.
|
|
14
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
15
|
*/
|
|
17
16
|
|
|
18
17
|
import { NoRetryError } from '@izara_project/izara-core-library-core';
|
|
@@ -22,558 +21,251 @@ import snsSharedLib from '@izara_project/izara-core-library-sns';
|
|
|
22
21
|
|
|
23
22
|
import { createParentFlowId } from './asyncFlowSharedLib.js';
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
// One pendingStepId can have multiple awaitingStepIds it is awaiting
|
|
29
|
-
// logic can prepend any prefix to awaitingStepId if want to be share one table and differentiate different external step ids
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Create multiple awaiting records with optional per-record additional attributes.
|
|
33
|
-
* Writes to both "AwaitingMultipleSteps" and "AwaitingMultipleStepByPending".
|
|
34
|
-
* @async
|
|
35
|
-
* @param {IzContext} _izContext
|
|
36
|
-
* @param {AwaitingMultiInputRecord[]} records
|
|
37
|
-
* @param {string} pendingStepId
|
|
38
|
-
* @returns {Promise<void>}
|
|
39
|
-
*/
|
|
40
|
-
export async function createAwaitingMultipleStepsWithAdditionalAttributes(
|
|
41
|
-
_izContext,
|
|
42
|
-
records, // array of object including properties: awaitingStepId / (optional) additionalAttributes
|
|
43
|
-
pendingStepId
|
|
44
|
-
) {
|
|
45
|
-
_izContext.logger.debug(
|
|
46
|
-
'[Lib:AsyncFlow:createAwaitingMultipleStepsWithAdditionalAttributes] Input: ',
|
|
47
|
-
{
|
|
48
|
-
records,
|
|
49
|
-
pendingStepId
|
|
50
|
-
}
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
const promiseArray = [];
|
|
54
|
-
|
|
55
|
-
for (const record of records) {
|
|
56
|
-
const attributesWhenCreate = {
|
|
57
|
-
awaitingStepId: record.awaitingStepId,
|
|
58
|
-
pendingStepId: pendingStepId,
|
|
59
|
-
timestamp: Date.now(),
|
|
60
|
-
...record.additionalAttributes
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
promiseArray.push(
|
|
64
|
-
dynamodbSharedLib.putItem(
|
|
65
|
-
_izContext,
|
|
66
|
-
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
|
|
67
|
-
attributesWhenCreate
|
|
68
|
-
)
|
|
69
|
-
);
|
|
70
|
-
promiseArray.push(
|
|
71
|
-
dynamodbSharedLib.putItem(
|
|
72
|
-
_izContext,
|
|
73
|
-
dynamodbSharedLib.tableName(
|
|
74
|
-
_izContext,
|
|
75
|
-
'AwaitingMultipleStepByPending'
|
|
76
|
-
),
|
|
77
|
-
{
|
|
78
|
-
pendingStepId: pendingStepId,
|
|
79
|
-
awaitingStepId: record.awaitingStepId,
|
|
80
|
-
timestamp: Date.now()
|
|
81
|
-
}
|
|
82
|
-
)
|
|
83
|
-
);
|
|
24
|
+
function _assertPendingStepId(pendingStepId) {
|
|
25
|
+
if (!pendingStepId) {
|
|
26
|
+
throw new NoRetryError('pendingStepId required');
|
|
84
27
|
}
|
|
85
|
-
|
|
86
|
-
await Promise.all(promiseArray);
|
|
87
28
|
}
|
|
88
29
|
|
|
89
|
-
|
|
90
|
-
* Batch initializes multiple pending steps in DynamoDB.
|
|
91
|
-
* Records status in both the primary tracking table and the pending-relation table.
|
|
92
|
-
* * @async
|
|
93
|
-
* @param {Object} _izContext - The system context providing logger and shared utilities.
|
|
94
|
-
* @param {Array<Object>} records - Array of step objects to be initialized.
|
|
95
|
-
* @param {string} records[].awaitingStepId - The unique identifier for the specific step.
|
|
96
|
-
* @param {Object} [records[].additionalAttributes] - Optional metadata to store with the step.
|
|
97
|
-
* @param {string} pendingStepId - The parent ID linking all related steps together.
|
|
98
|
-
* @returns {Promise<void>}
|
|
99
|
-
*/
|
|
100
|
-
export async function initAwaitingStepsWithAttrs(
|
|
30
|
+
async function _putAwaitingMultipleStepRecords(
|
|
101
31
|
_izContext,
|
|
102
32
|
records,
|
|
103
|
-
pendingStepId
|
|
104
|
-
) {
|
|
105
|
-
_izContext.logger.debug(
|
|
106
|
-
'[Lib:AsyncFlow:initAwaitingStepsWithAttrs] Input: ',
|
|
107
|
-
{
|
|
108
|
-
records,
|
|
109
|
-
pendingStepId
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
const timestamp = Date.now();
|
|
114
|
-
const promiseArray = [];
|
|
115
|
-
|
|
116
|
-
for (const record of records) {
|
|
117
|
-
promiseArray.push(
|
|
118
|
-
dynamodbSharedLib.putItem(
|
|
119
|
-
_izContext,
|
|
120
|
-
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
|
|
121
|
-
{
|
|
122
|
-
awaitingStepId: record.awaitingStepId,
|
|
123
|
-
pendingStepId,
|
|
124
|
-
timestamp
|
|
125
|
-
}
|
|
126
|
-
)
|
|
127
|
-
);
|
|
128
|
-
promiseArray.push(
|
|
129
|
-
dynamodbSharedLib.putItem(
|
|
130
|
-
_izContext,
|
|
131
|
-
dynamodbSharedLib.tableName(
|
|
132
|
-
_izContext,
|
|
133
|
-
'AwaitingMultipleStepByPending'
|
|
134
|
-
),
|
|
135
|
-
{
|
|
136
|
-
pendingStepId,
|
|
137
|
-
awaitingStepId: record.awaitingStepId,
|
|
138
|
-
timestamp,
|
|
139
|
-
...record.additionalAttributes
|
|
140
|
-
}
|
|
141
|
-
)
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
await Promise.all(promiseArray);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Create multiple awaiting records given an array of awaitingStepIds.
|
|
150
|
-
* Writes to both "AwaitingMultipleSteps" and "AwaitingMultipleStepByPending".
|
|
151
|
-
* @async
|
|
152
|
-
* @param {IzContext} _izContext
|
|
153
|
-
* @param {string[]} records - array of awaitingStepIds
|
|
154
|
-
* @param {string} pendingStepId
|
|
155
|
-
* @returns {Promise<void>}
|
|
156
|
-
*/
|
|
157
|
-
export async function createAwaitingMultipleSteps(
|
|
158
|
-
_izContext,
|
|
159
|
-
records, // array of awaitingStepIds
|
|
160
|
-
pendingStepId
|
|
161
|
-
) {
|
|
162
|
-
_izContext.logger.debug(
|
|
163
|
-
'[Lib:AsyncFlow:createAwaitingMultipleSteps] Input: ',
|
|
164
|
-
{
|
|
165
|
-
records: records,
|
|
166
|
-
pendingStepId: pendingStepId
|
|
167
|
-
}
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
const promiseArray = [];
|
|
171
|
-
|
|
172
|
-
for (const record of records) {
|
|
173
|
-
const attributesWhenCreate = {
|
|
174
|
-
awaitingStepId: record,
|
|
175
|
-
pendingStepId: pendingStepId,
|
|
176
|
-
timestamp: Date.now()
|
|
177
|
-
};
|
|
178
|
-
_izContext.logger.debug(
|
|
179
|
-
'[Lib:AsyncFlow:createAwaitingMultipleSteps] attributesWhenCreate: ',
|
|
180
|
-
attributesWhenCreate
|
|
181
|
-
);
|
|
182
|
-
promiseArray.push(
|
|
183
|
-
dynamodbSharedLib.putItem(
|
|
184
|
-
_izContext,
|
|
185
|
-
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
|
|
186
|
-
attributesWhenCreate
|
|
187
|
-
)
|
|
188
|
-
);
|
|
189
|
-
|
|
190
|
-
_izContext.logger.debug(
|
|
191
|
-
'[Lib:AsyncFlow:createAwaitingMultipleSteps] putItem:AwaitingMultipleStepByPending',
|
|
192
|
-
{
|
|
193
|
-
awaitingStepId: attributesWhenCreate.awaitingStepId
|
|
194
|
-
}
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
promiseArray.push(
|
|
198
|
-
dynamodbSharedLib.putItem(
|
|
199
|
-
_izContext,
|
|
200
|
-
dynamodbSharedLib.tableName(
|
|
201
|
-
_izContext,
|
|
202
|
-
'AwaitingMultipleStepByPending'
|
|
203
|
-
),
|
|
204
|
-
attributesWhenCreate
|
|
205
|
-
)
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
await Promise.all(promiseArray);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Create new awaiting multiple steps for a pending step.
|
|
214
|
-
* @async
|
|
215
|
-
* @param {IzContext} _izContext
|
|
216
|
-
* @param {string} pendingStepId
|
|
217
|
-
* @param {string[]} parendIds
|
|
218
|
-
* @param {Object.<string, any>} [additionalAttributes={}] - Shared attributes stored for every step in AwaitingMultipleStepByPending.
|
|
219
|
-
* The same object is applied to all steps (caller cannot know the generated UUIDs beforehand).
|
|
220
|
-
* @returns {Promise<string>} The awaiting step ID created.
|
|
221
|
-
*/
|
|
222
|
-
export async function createNewAwaitingMultipleStep(
|
|
223
|
-
_izContext,
|
|
224
33
|
pendingStepId,
|
|
225
|
-
|
|
226
|
-
additionalAttributes = {}
|
|
34
|
+
sharedAttributes = {}
|
|
227
35
|
) {
|
|
228
|
-
|
|
229
|
-
'[Lib:AsyncFlow:createNewAwaitingMultipleStep] Input: ',
|
|
230
|
-
{
|
|
231
|
-
pendingStepId,
|
|
232
|
-
additionalAttributes
|
|
233
|
-
}
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
const parentFlowId = createParentFlowId(prefix);
|
|
237
|
-
|
|
238
|
-
const attributesWhenCreate = {
|
|
239
|
-
awaitingStepId: parentFlowId,
|
|
240
|
-
pendingStepId: pendingStepId,
|
|
241
|
-
complete: false,
|
|
242
|
-
errorsFound: []
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
_izContext.logger.debug(
|
|
246
|
-
'[Lib:AsyncFlow:createNewAwaitingMultipleStep] attributesWhenCreate: ',
|
|
247
|
-
attributesWhenCreate
|
|
248
|
-
);
|
|
249
|
-
|
|
250
|
-
await dynamodbSharedLib.putItem(
|
|
36
|
+
const tableSteps = dynamodbSharedLib.tableName(
|
|
251
37
|
_izContext,
|
|
252
|
-
|
|
253
|
-
attributesWhenCreate
|
|
38
|
+
'AwaitingMultipleSteps'
|
|
254
39
|
);
|
|
255
|
-
|
|
256
|
-
const attributesForPending = {
|
|
257
|
-
...attributesWhenCreate,
|
|
258
|
-
additionalAttributes: additionalAttributes
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
await dynamodbSharedLib.putItem(
|
|
40
|
+
const tablePending = dynamodbSharedLib.tableName(
|
|
262
41
|
_izContext,
|
|
263
|
-
|
|
264
|
-
attributesForPending
|
|
42
|
+
'AwaitingMultipleStepByPending'
|
|
265
43
|
);
|
|
266
44
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
45
|
+
await Promise.all(
|
|
46
|
+
records.flatMap(({ awaitingStepId, additionalAttributes }) => {
|
|
47
|
+
const keys = { awaitingStepId, pendingStepId };
|
|
48
|
+
|
|
49
|
+
return [
|
|
50
|
+
dynamodbSharedLib.putItem(_izContext, tableSteps, keys),
|
|
51
|
+
dynamodbSharedLib.putItem(_izContext, tablePending, {
|
|
52
|
+
...keys,
|
|
53
|
+
...sharedAttributes,
|
|
54
|
+
...(additionalAttributes && { additionalAttributes })
|
|
55
|
+
})
|
|
56
|
+
];
|
|
57
|
+
})
|
|
270
58
|
);
|
|
271
|
-
|
|
272
|
-
return parentFlowId;
|
|
273
59
|
}
|
|
274
60
|
|
|
275
|
-
|
|
276
|
-
* Find all pendingStepIds that are waiting on a given awaitingStepId (multiple).
|
|
277
|
-
* @async
|
|
278
|
-
* @param {IzContext} _izContext
|
|
279
|
-
* @param {string} awaitingStepId
|
|
280
|
-
* @returns {Promise<string[]>}
|
|
281
|
-
*/
|
|
282
|
-
export async function findPendingStepIdsAwaitingMultipleSteps(
|
|
283
|
-
_izContext,
|
|
284
|
-
awaitingStepId
|
|
285
|
-
) {
|
|
286
|
-
_izContext.logger.debug(
|
|
287
|
-
'[Lib:findPendingStepIdsAwaitingMultipleSteps] Input parameters',
|
|
288
|
-
{
|
|
289
|
-
awaitingStepId: awaitingStepId
|
|
290
|
-
}
|
|
291
|
-
);
|
|
292
|
-
|
|
61
|
+
async function _queryPendingStepsByAwaitingStepId(_izContext, awaitingStepId) {
|
|
293
62
|
if (!awaitingStepId) {
|
|
294
|
-
|
|
295
|
-
'[Lib:findPendingStepIdsAwaitingMultipleSteps] awaitingStepId is required'
|
|
296
|
-
);
|
|
297
|
-
throw new NoRetryError('awaitingStepId is required');
|
|
63
|
+
throw new NoRetryError('awaitingStepId required');
|
|
298
64
|
}
|
|
299
65
|
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
const listPendingStepIds = await dynamodbSharedLib.query(
|
|
66
|
+
const { Items } = await dynamodbSharedLib.query(
|
|
303
67
|
_izContext,
|
|
304
68
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
|
|
305
|
-
{
|
|
306
|
-
awaitingStepId: awaitingStepId
|
|
307
|
-
}
|
|
69
|
+
{ awaitingStepId }
|
|
308
70
|
);
|
|
309
71
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
}
|
|
72
|
+
return Items;
|
|
73
|
+
}
|
|
313
74
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
75
|
+
async function _queryAwaitingStepsByPendingStepId(_izContext, pendingStepId) {
|
|
76
|
+
_assertPendingStepId(pendingStepId);
|
|
77
|
+
|
|
78
|
+
const { Items } = await dynamodbSharedLib.query(
|
|
79
|
+
_izContext,
|
|
80
|
+
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleStepByPending'),
|
|
81
|
+
{ pendingStepId },
|
|
82
|
+
{ limit: 50 }
|
|
317
83
|
);
|
|
318
84
|
|
|
319
|
-
return
|
|
85
|
+
return Items;
|
|
320
86
|
}
|
|
321
87
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
export async function
|
|
88
|
+
//======================================
|
|
89
|
+
// AwaitingMultipleSteps
|
|
90
|
+
//======================================
|
|
91
|
+
// AwaitingMultipleSteps flow awaits multiple external flows before continuing.
|
|
92
|
+
// One awaitingStepId can have multiple pendingStepIds awaiting it.
|
|
93
|
+
// One pendingStepId can have multiple awaitingStepIds awaiting it.
|
|
94
|
+
|
|
95
|
+
export async function createAwaitingMultipleSteps(
|
|
330
96
|
_izContext,
|
|
331
|
-
|
|
97
|
+
pendingStepId,
|
|
98
|
+
options = {}
|
|
332
99
|
) {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
100
|
+
const {
|
|
101
|
+
records = [],
|
|
102
|
+
prefix = '',
|
|
103
|
+
additionalAttributes = {},
|
|
104
|
+
publishConfig = null
|
|
105
|
+
} = options;
|
|
106
|
+
|
|
107
|
+
_izContext.logger.debug('[Lib:AsyncFlow:createAwaitingMultipleSteps] Input', {
|
|
108
|
+
pendingStepId,
|
|
109
|
+
options
|
|
110
|
+
});
|
|
339
111
|
|
|
340
|
-
|
|
341
|
-
_izContext.logger.error(
|
|
342
|
-
'[Lib:findPendingStepsAwaitingMultipleSteps] awaitingStepId is required'
|
|
343
|
-
);
|
|
344
|
-
throw new NoRetryError('awaitingStepId is required');
|
|
345
|
-
}
|
|
112
|
+
let finalRecords = records;
|
|
346
113
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
114
|
+
if (finalRecords.length === 0 && !publishConfig) {
|
|
115
|
+
finalRecords = [
|
|
116
|
+
{
|
|
117
|
+
awaitingStepId: createParentFlowId(prefix),
|
|
118
|
+
additionalAttributes
|
|
119
|
+
}
|
|
120
|
+
];
|
|
121
|
+
}
|
|
354
122
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
);
|
|
123
|
+
if (publishConfig) {
|
|
124
|
+
const { messages, flowType = {} } = publishConfig;
|
|
125
|
+
const { flowTag, serviceTag } = flowType;
|
|
359
126
|
|
|
360
|
-
|
|
361
|
-
|
|
127
|
+
if (!Array.isArray(messages)) {
|
|
128
|
+
throw new NoRetryError('messages must be an array');
|
|
129
|
+
}
|
|
362
130
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
* @async
|
|
366
|
-
* @param {IzContext} _izContext
|
|
367
|
-
* @param {string} awaitingStepId
|
|
368
|
-
* @returns {Promise<AwaitingMultipleStepsItem>}
|
|
369
|
-
* @throws {NoRetryError} if there is not exactly one item
|
|
370
|
-
*/
|
|
371
|
-
export async function findPendingStepAwaitingMultipleSteps(
|
|
372
|
-
_izContext,
|
|
373
|
-
awaitingStepId
|
|
374
|
-
) {
|
|
375
|
-
_izContext.logger.debug(
|
|
376
|
-
'[Lib:findPendingStepAwaitingMultipleSteps] Input parameters',
|
|
377
|
-
{
|
|
378
|
-
awaitingStepId: awaitingStepId
|
|
131
|
+
if (!flowTag || !serviceTag) {
|
|
132
|
+
throw new NoRetryError('flowType must both flowTag serviceTag');
|
|
379
133
|
}
|
|
380
|
-
);
|
|
381
134
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
135
|
+
finalRecords = messages.map(message => {
|
|
136
|
+
const parentFlowId = createParentFlowId(prefix);
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
awaitingStepId: parentFlowId,
|
|
140
|
+
additionalAttributes,
|
|
141
|
+
message: {
|
|
142
|
+
...message,
|
|
143
|
+
parentFlowId
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
});
|
|
387
147
|
}
|
|
388
148
|
|
|
389
|
-
|
|
149
|
+
await _putAwaitingMultipleStepRecords(
|
|
390
150
|
_izContext,
|
|
391
|
-
|
|
151
|
+
finalRecords.map(({ awaitingStepId, additionalAttributes: itemAttrs }) => ({
|
|
152
|
+
awaitingStepId,
|
|
153
|
+
additionalAttributes: itemAttrs
|
|
154
|
+
})),
|
|
155
|
+
pendingStepId,
|
|
392
156
|
{
|
|
393
|
-
|
|
157
|
+
complete: false,
|
|
158
|
+
errorsFound: []
|
|
394
159
|
}
|
|
395
160
|
);
|
|
396
161
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
162
|
+
if (publishConfig) {
|
|
163
|
+
const topicArn = snsSharedLib.snsTopicArnByFlowSchema(
|
|
164
|
+
_izContext,
|
|
165
|
+
publishConfig.flowType.flowTag,
|
|
166
|
+
publishConfig.flowType.serviceTag
|
|
167
|
+
);
|
|
401
168
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
169
|
+
await Promise.all(
|
|
170
|
+
finalRecords.map(({ message }) =>
|
|
171
|
+
sns.publishAsync(_izContext, {
|
|
172
|
+
TopicArn: `${topicArn}_In`,
|
|
173
|
+
Message: JSON.stringify(message),
|
|
174
|
+
MessageAttributes: {}
|
|
175
|
+
})
|
|
176
|
+
)
|
|
405
177
|
);
|
|
406
|
-
throw new NoRetryError('listPendingSteps not equals 1');
|
|
407
178
|
}
|
|
408
179
|
|
|
409
|
-
return
|
|
180
|
+
return finalRecords[0]?.awaitingStepId;
|
|
410
181
|
}
|
|
411
182
|
|
|
412
|
-
|
|
413
|
-
// Use only after checkAllAwaitingStepsFinished
|
|
414
|
-
// Do NOT delete records in both tables (AwaitingMultipleSteps, AwaitingMultipleStepByPending) if AwaitingMultipleSteps is not yet finished
|
|
415
|
-
// Delete records from both tables only when checkAllAwaitingStepsFinished = true
|
|
416
|
-
// Example usage: flow validateCart lambda ProcessCartOrderFromTraversal
|
|
417
|
-
/**
|
|
418
|
-
* Given a pendingStepId, return all awaiting steps (by the ByPending table).
|
|
419
|
-
* Use only after confirming all awaiting steps are finished, and clean up both tables accordingly.
|
|
420
|
-
* @async
|
|
421
|
-
* @param {IzContext} _izContext
|
|
422
|
-
* @param {string} pendingStepId
|
|
423
|
-
* @returns {Promise<AwaitingMultipleStepByPendingItem[]>}
|
|
424
|
-
*/
|
|
425
|
-
export async function findAwaitingMultipleStepByPending(
|
|
183
|
+
export async function createAwaitingMultipleStepsWithAdditionalAttributes(
|
|
426
184
|
_izContext,
|
|
185
|
+
records,
|
|
427
186
|
pendingStepId
|
|
428
187
|
) {
|
|
429
|
-
_izContext
|
|
430
|
-
'[Lib:findAwaitingMultipleStepByPending] Input parameters',
|
|
431
|
-
{
|
|
432
|
-
pendingStepId: pendingStepId
|
|
433
|
-
}
|
|
434
|
-
);
|
|
435
|
-
|
|
436
|
-
if (!pendingStepId) {
|
|
437
|
-
_izContext.logger.error(
|
|
438
|
-
'[Lib:findAwaitingMultipleStepByPending] pendingStepId is required'
|
|
439
|
-
);
|
|
440
|
-
throw new NoRetryError('pendingStepId is required');
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
const listAwaitingSteps = await dynamodbSharedLib.query(
|
|
444
|
-
_izContext,
|
|
445
|
-
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleStepByPending'),
|
|
446
|
-
{
|
|
447
|
-
pendingStepId: pendingStepId
|
|
448
|
-
}
|
|
449
|
-
);
|
|
450
|
-
_izContext.logger.debug(
|
|
451
|
-
'[Lib:findAwaitingMultipleStepByPending] Record of AwaitingMultipleStepByPending',
|
|
452
|
-
listAwaitingSteps
|
|
453
|
-
);
|
|
454
|
-
|
|
455
|
-
return listAwaitingSteps.Items;
|
|
188
|
+
return createAwaitingMultipleSteps(_izContext, pendingStepId, { records });
|
|
456
189
|
}
|
|
457
190
|
|
|
458
|
-
|
|
459
|
-
* Updates the completion status of a specific awaiting step within a multiple-step pending process.
|
|
460
|
-
* Marks the given awaiting step as complete and stores any encountered errors or additional attributes.
|
|
461
|
-
*
|
|
462
|
-
* @param {Object} _izContext - The execution context object containing logger and other utilities.
|
|
463
|
-
* @param {string} pendingStepId - The unique identifier of the parent pending step.
|
|
464
|
-
* @param {string|null} [currentAwaitingStepId=null] - The unique identifier of the specific awaiting step being processed. If null, no update is performed.
|
|
465
|
-
* @param {Array<Object|string>} [errorsFound=[]] - An array of errors encountered during the step's execution.
|
|
466
|
-
* @param {Object} [additionalAttributes={}] - Any extra data to save along with the completion status.
|
|
467
|
-
* @returns {Promise<void>} Resolves when the update operation is complete.
|
|
468
|
-
*/
|
|
469
|
-
export async function checkAllAwaitingStepsFinishedShared(
|
|
191
|
+
export async function createAwaitingMultipleStep(
|
|
470
192
|
_izContext,
|
|
471
193
|
pendingStepId,
|
|
472
|
-
|
|
473
|
-
errorsFound = [],
|
|
194
|
+
prefix = '',
|
|
474
195
|
additionalAttributes = {}
|
|
475
196
|
) {
|
|
476
|
-
_izContext
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
currentAwaitingStepId: currentAwaitingStepId,
|
|
481
|
-
errorsFound: errorsFound
|
|
482
|
-
}
|
|
483
|
-
);
|
|
484
|
-
|
|
485
|
-
if (currentAwaitingStepId) {
|
|
486
|
-
await dynamodbSharedLib.updateItem(
|
|
487
|
-
_izContext,
|
|
488
|
-
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleStepByPending'),
|
|
489
|
-
{
|
|
490
|
-
pendingStepId: pendingStepId,
|
|
491
|
-
awaitingStepId: currentAwaitingStepId
|
|
492
|
-
},
|
|
493
|
-
{
|
|
494
|
-
complete: true,
|
|
495
|
-
errorsFound: errorsFound,
|
|
496
|
-
additionalAttributes: additionalAttributes
|
|
497
|
-
}
|
|
498
|
-
);
|
|
499
|
-
}
|
|
197
|
+
return createAwaitingMultipleSteps(_izContext, pendingStepId, {
|
|
198
|
+
prefix,
|
|
199
|
+
additionalAttributes
|
|
200
|
+
});
|
|
500
201
|
}
|
|
501
202
|
|
|
502
|
-
|
|
503
|
-
* Same as checkAllAwaitingStepsFinished but writes errors/additionalAttributes to the *_ByPending row.
|
|
504
|
-
* @async
|
|
505
|
-
* @param {IzContext} _izContext
|
|
506
|
-
* @param {string} pendingStepId
|
|
507
|
-
* @param {string|null} [currentAwaitingStepId=null]
|
|
508
|
-
* @param {any[]} [errorsFound=[]]
|
|
509
|
-
* @param {Attrs} [additionalAttributes={}]
|
|
510
|
-
* @returns {Promise<boolean>}
|
|
511
|
-
*/
|
|
512
|
-
export async function checkAllAwaitingStepsFinished(
|
|
203
|
+
export async function createAwaitingMultipleStepsWithAdditionalAttributesAndPublish(
|
|
513
204
|
_izContext,
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
additionalAttributes = {}
|
|
205
|
+
messages,
|
|
206
|
+
prefix = '',
|
|
207
|
+
flowType = {},
|
|
208
|
+
additionalAttributes = {},
|
|
209
|
+
pendingStepId
|
|
518
210
|
) {
|
|
519
|
-
_izContext
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
211
|
+
return createAwaitingMultipleSteps(_izContext, pendingStepId, {
|
|
212
|
+
prefix,
|
|
213
|
+
additionalAttributes,
|
|
214
|
+
publishConfig: {
|
|
215
|
+
messages,
|
|
216
|
+
flowType
|
|
525
217
|
}
|
|
526
|
-
);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
527
220
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
);
|
|
221
|
+
export async function findPendingStepAwaitingMultipleSteps(
|
|
222
|
+
_izContext,
|
|
223
|
+
awaitingStepId
|
|
224
|
+
) {
|
|
225
|
+
_izContext.logger.debug('[Lib:findPendingStepAwaitingMultipleSteps] Input', {
|
|
226
|
+
awaitingStepId
|
|
227
|
+
});
|
|
535
228
|
|
|
536
|
-
const items = await
|
|
229
|
+
const items = await _queryPendingStepsByAwaitingStepId(
|
|
537
230
|
_izContext,
|
|
538
|
-
|
|
539
|
-
{ pendingStepId },
|
|
540
|
-
{ limit: 50 }
|
|
231
|
+
awaitingStepId
|
|
541
232
|
);
|
|
542
233
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
if (!item.complete) return false;
|
|
546
|
-
}
|
|
234
|
+
return items[0];
|
|
235
|
+
}
|
|
547
236
|
|
|
548
|
-
|
|
549
|
-
|
|
237
|
+
export async function findPendingStepsAwaitingMultipleSteps(
|
|
238
|
+
_izContext,
|
|
239
|
+
awaitingStepId
|
|
240
|
+
) {
|
|
241
|
+
return _queryPendingStepsByAwaitingStepId(_izContext, awaitingStepId);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export async function findPendingStepIdAwaitingMultipleSteps(
|
|
245
|
+
_izContext,
|
|
246
|
+
awaitingStepId
|
|
247
|
+
) {
|
|
248
|
+
const items = await _queryPendingStepsByAwaitingStepId(
|
|
249
|
+
_izContext,
|
|
250
|
+
awaitingStepId
|
|
550
251
|
);
|
|
551
|
-
return
|
|
252
|
+
return items[0]?.pendingStepId;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export async function findAwaitingMultipleStepByPending(
|
|
256
|
+
_izContext,
|
|
257
|
+
pendingStepId
|
|
258
|
+
) {
|
|
259
|
+
return _queryAwaitingStepsByPendingStepId(_izContext, pendingStepId);
|
|
552
260
|
}
|
|
553
261
|
|
|
554
|
-
/**
|
|
555
|
-
* Checks if all awaiting steps for a pending step are complete after marking the current one as complete.
|
|
556
|
-
* If all steps are finished, returns an object with `isComplete: true` and the collected data.
|
|
557
|
-
* If any other step is not yet complete, returns `isComplete: false` with null data.
|
|
558
|
-
* @async
|
|
559
|
-
* @param {IzContext} _izContext
|
|
560
|
-
* @param {string} pendingStepId
|
|
561
|
-
* @param {string|null} [currentAwaitingStepId=null] - The step that has just finished.
|
|
562
|
-
* @param {any[]} [errorsFound=[]]
|
|
563
|
-
* @param {Attrs} [additionalAttributes={}]
|
|
564
|
-
* @returns {Promise<{
|
|
565
|
-
* isComplete: boolean,
|
|
566
|
-
* collectedAttributes: Record<string, any>|null,
|
|
567
|
-
* collectedErrors: any[],
|
|
568
|
-
* sharedAdditionalAttributes: any|null
|
|
569
|
-
* }>}
|
|
570
|
-
*/
|
|
571
262
|
export async function checkAllAwaitingStepsFinishedWithReturnParams(
|
|
572
263
|
_izContext,
|
|
573
264
|
pendingStepId,
|
|
574
265
|
currentAwaitingStepId = null,
|
|
575
266
|
errorsFound = [],
|
|
576
|
-
|
|
267
|
+
returnValues = {},
|
|
268
|
+
settings = { checkIsAllError: true }
|
|
577
269
|
) {
|
|
578
270
|
_izContext.logger.debug(
|
|
579
271
|
'[Lib:checkAllAwaitingStepsFinishedWithReturnParams] Input parameters',
|
|
@@ -581,159 +273,117 @@ export async function checkAllAwaitingStepsFinishedWithReturnParams(
|
|
|
581
273
|
pendingStepId,
|
|
582
274
|
currentAwaitingStepId,
|
|
583
275
|
errorsFound,
|
|
584
|
-
|
|
276
|
+
returnValues
|
|
585
277
|
}
|
|
586
278
|
);
|
|
587
279
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
280
|
+
_assertPendingStepId(pendingStepId);
|
|
281
|
+
|
|
282
|
+
if (currentAwaitingStepId) {
|
|
283
|
+
await dynamodbSharedLib.updateItem(
|
|
284
|
+
_izContext,
|
|
285
|
+
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleStepByPending'),
|
|
286
|
+
{
|
|
287
|
+
pendingStepId,
|
|
288
|
+
awaitingStepId: currentAwaitingStepId
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
complete: true,
|
|
292
|
+
errorsFound,
|
|
293
|
+
returnValues
|
|
294
|
+
}
|
|
591
295
|
);
|
|
592
296
|
}
|
|
593
297
|
|
|
594
|
-
await
|
|
298
|
+
const awaitingStepItems = await _queryAwaitingStepsByPendingStepId(
|
|
595
299
|
_izContext,
|
|
596
|
-
pendingStepId
|
|
597
|
-
currentAwaitingStepId,
|
|
598
|
-
errorsFound,
|
|
599
|
-
additionalAttributes
|
|
600
|
-
);
|
|
601
|
-
|
|
602
|
-
const awaitingStepItems = await dynamodbSharedLib.query(
|
|
603
|
-
_izContext,
|
|
604
|
-
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleStepByPending'),
|
|
605
|
-
{ pendingStepId },
|
|
606
|
-
{ limit: 50 }
|
|
300
|
+
pendingStepId
|
|
607
301
|
);
|
|
608
302
|
|
|
609
303
|
_izContext.logger.debug(
|
|
610
|
-
'[Lib:checkAllAwaitingStepsFinishedWithReturnParams] awaitingStepItems
|
|
304
|
+
'[Lib:checkAllAwaitingStepsFinishedWithReturnParams] awaitingStepItems',
|
|
611
305
|
awaitingStepItems
|
|
612
306
|
);
|
|
613
307
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
if (item.awaitingStepId !== currentAwaitingStepId && !item.complete) {
|
|
617
|
-
return {
|
|
618
|
-
isComplete: false,
|
|
619
|
-
collectedAttributes: null,
|
|
620
|
-
collectedErrors: [],
|
|
621
|
-
sharedAdditionalAttributes: null
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
_izContext.logger.debug(
|
|
627
|
-
'[Lib:checkAllAwaitingStepsFinishedWithReturnParams] Pass 1: all steps are complete'
|
|
308
|
+
const hasIncomplete = awaitingStepItems.some(
|
|
309
|
+
item => item.awaitingStepId !== currentAwaitingStepId && !item.complete
|
|
628
310
|
);
|
|
629
311
|
|
|
630
|
-
|
|
312
|
+
if (hasIncomplete) {
|
|
313
|
+
return {
|
|
314
|
+
isComplete: false,
|
|
315
|
+
collectedAttributes: null,
|
|
316
|
+
collectedErrors: [],
|
|
317
|
+
returnValues: null
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
631
321
|
const collectedAttributes = {};
|
|
632
|
-
|
|
633
|
-
let sharedAdditionalAttributes = null;
|
|
322
|
+
let sharedReturnValues = null;
|
|
634
323
|
|
|
635
|
-
for (const item of awaitingStepItems
|
|
636
|
-
if (item.
|
|
637
|
-
|
|
324
|
+
for (const item of awaitingStepItems) {
|
|
325
|
+
if (!item.returnValues) {
|
|
326
|
+
continue;
|
|
638
327
|
}
|
|
639
328
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
if (sharedAdditionalAttributes === null) {
|
|
643
|
-
sharedAdditionalAttributes = item.additionalAttributes;
|
|
644
|
-
}
|
|
645
|
-
}
|
|
329
|
+
collectedAttributes[item.awaitingStepId] = item.returnValues;
|
|
330
|
+
sharedReturnValues ??= item.returnValues;
|
|
646
331
|
}
|
|
647
332
|
|
|
648
|
-
|
|
649
|
-
|
|
333
|
+
const collectedErrors = awaitingStepItems.flatMap(item =>
|
|
334
|
+
item.errorsFound?.length > 0
|
|
335
|
+
? [`Error found in step ${item.awaitingStepId}`, ...item.errorsFound]
|
|
336
|
+
: []
|
|
650
337
|
);
|
|
651
338
|
|
|
652
339
|
return {
|
|
653
340
|
isComplete: true,
|
|
654
341
|
collectedAttributes,
|
|
655
342
|
collectedErrors,
|
|
656
|
-
|
|
343
|
+
returnValues: sharedReturnValues,
|
|
344
|
+
additionalAttributes: awaitingStepItems[0]?.additionalAttributes || null,
|
|
345
|
+
...(settings.checkIsAllError && {
|
|
346
|
+
isAllError: awaitingStepItems.every(item => item.errorsFound?.length > 0)
|
|
347
|
+
})
|
|
657
348
|
};
|
|
658
349
|
}
|
|
659
350
|
|
|
660
|
-
/**
|
|
661
|
-
* Remove all awaiting records for a given pendingStepId from both tables.
|
|
662
|
-
* @async
|
|
663
|
-
* @param {IzContext} _izContext
|
|
664
|
-
* @param {string} pendingStepId
|
|
665
|
-
* @returns {Promise<boolean>} true if delete flow processed
|
|
666
|
-
*/
|
|
667
351
|
export async function clearAllAwaitingSteps(_izContext, pendingStepId) {
|
|
668
352
|
_izContext.logger.debug('[Lib:clearAllAwaitingSteps] Input parameters', {
|
|
669
|
-
pendingStepId
|
|
353
|
+
pendingStepId
|
|
670
354
|
});
|
|
671
355
|
|
|
672
|
-
|
|
673
|
-
throw NoRetryError('[Lib:clearAllAwaitingSteps] pendingStepId is required');
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
// ----- query items from GSI table
|
|
677
|
-
const listPendingStepIds = await dynamodbSharedLib.query(
|
|
356
|
+
const listPendingStepIds = await _queryAwaitingStepsByPendingStepId(
|
|
678
357
|
_izContext,
|
|
679
|
-
|
|
680
|
-
{
|
|
681
|
-
pendingStepId: pendingStepId
|
|
682
|
-
}
|
|
358
|
+
pendingStepId
|
|
683
359
|
);
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
360
|
+
const tableSteps = dynamodbSharedLib.tableName(
|
|
361
|
+
_izContext,
|
|
362
|
+
'AwaitingMultipleSteps'
|
|
363
|
+
);
|
|
364
|
+
const tablePending = dynamodbSharedLib.tableName(
|
|
365
|
+
_izContext,
|
|
366
|
+
'AwaitingMultipleStepByPending'
|
|
687
367
|
);
|
|
688
368
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
dynamodbSharedLib.
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
_izContext.logger.debug(
|
|
705
|
-
'[Lib:clearAllAwaitingSteps] delete item in dynamodb AwaitingMultipleStepByPending'
|
|
706
|
-
);
|
|
707
|
-
promiseArray.push(
|
|
708
|
-
dynamodbSharedLib.deleteItem(
|
|
709
|
-
_izContext,
|
|
710
|
-
dynamodbSharedLib.tableName(
|
|
711
|
-
_izContext,
|
|
712
|
-
'AwaitingMultipleStepByPending'
|
|
713
|
-
),
|
|
714
|
-
{
|
|
715
|
-
pendingStepId: listPendingStepIds.Items[idx].pendingStepId,
|
|
716
|
-
awaitingStepId: listPendingStepIds.Items[idx].awaitingStepId
|
|
717
|
-
}
|
|
718
|
-
)
|
|
719
|
-
);
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
await Promise.all(promiseArray);
|
|
369
|
+
await Promise.all(
|
|
370
|
+
listPendingStepIds.flatMap(
|
|
371
|
+
({ awaitingStepId, pendingStepId: itemPendingStepId }) => [
|
|
372
|
+
dynamodbSharedLib.deleteItem(_izContext, tableSteps, {
|
|
373
|
+
awaitingStepId,
|
|
374
|
+
pendingStepId: itemPendingStepId
|
|
375
|
+
}),
|
|
376
|
+
dynamodbSharedLib.deleteItem(_izContext, tablePending, {
|
|
377
|
+
awaitingStepId,
|
|
378
|
+
pendingStepId: itemPendingStepId
|
|
379
|
+
})
|
|
380
|
+
]
|
|
381
|
+
)
|
|
382
|
+
);
|
|
723
383
|
|
|
724
384
|
return true;
|
|
725
385
|
}
|
|
726
386
|
|
|
727
|
-
/**
|
|
728
|
-
* Remove items for AwaitingMultipleSteps and (conditionally) AwaitingMultipleStepByPending.
|
|
729
|
-
* If errorsFound is empty, delete from ByPending table as well.
|
|
730
|
-
* @async
|
|
731
|
-
* @param {IzContext} _izContext
|
|
732
|
-
* @param {string} awaitingStepId
|
|
733
|
-
* @param {string} pendingStepId
|
|
734
|
-
* @param {any[]} [errorsFound=[]]
|
|
735
|
-
* @returns {Promise<void>}
|
|
736
|
-
*/
|
|
737
387
|
export async function removeAwaitingMultipleStep(
|
|
738
388
|
_izContext,
|
|
739
389
|
awaitingStepId,
|
|
@@ -741,148 +391,38 @@ export async function removeAwaitingMultipleStep(
|
|
|
741
391
|
errorsFound = []
|
|
742
392
|
) {
|
|
743
393
|
_izContext.logger.debug('[Lib:removeAwaitingMultipleStep] Input parameters', {
|
|
744
|
-
awaitingStepId
|
|
745
|
-
pendingStepId
|
|
746
|
-
errorsFound
|
|
394
|
+
awaitingStepId,
|
|
395
|
+
pendingStepId,
|
|
396
|
+
errorsFound
|
|
747
397
|
});
|
|
748
398
|
|
|
749
399
|
if (!awaitingStepId || !pendingStepId) {
|
|
750
|
-
throw NoRetryError(
|
|
751
|
-
'[Lib:removeAwaitingMultipleStep] awaitingStepId or pendingStepId
|
|
400
|
+
throw new NoRetryError(
|
|
401
|
+
'[Lib:removeAwaitingMultipleStep] awaitingStepId or pendingStepId required'
|
|
752
402
|
);
|
|
753
403
|
}
|
|
754
404
|
|
|
755
|
-
const
|
|
756
|
-
|
|
757
|
-
const keyValues = {
|
|
758
|
-
awaitingStepId: awaitingStepId,
|
|
759
|
-
pendingStepId: pendingStepId
|
|
760
|
-
};
|
|
761
|
-
|
|
762
|
-
const keyValuesForByPending = {
|
|
763
|
-
pendingStepId: pendingStepId,
|
|
764
|
-
awaitingStepId: awaitingStepId
|
|
765
|
-
};
|
|
766
|
-
_izContext.logger.debug('deleting ... ', {
|
|
767
|
-
keyValues,
|
|
768
|
-
keyValuesForByPending
|
|
769
|
-
});
|
|
770
|
-
|
|
771
|
-
_izContext.logger.debug(
|
|
772
|
-
'[Lib:removeAwaitingMultipleStep] delete item in dynamodb AwaitingMultipleSteps',
|
|
773
|
-
{
|
|
774
|
-
awaitingStepId: keyValues.awaitingStepId,
|
|
775
|
-
pendingStepId: keyValues.pendingStepId
|
|
776
|
-
}
|
|
777
|
-
);
|
|
778
|
-
promiseArray.push(
|
|
405
|
+
const keys = { awaitingStepId, pendingStepId };
|
|
406
|
+
const promises = [
|
|
779
407
|
dynamodbSharedLib.deleteItem(
|
|
780
408
|
_izContext,
|
|
781
409
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
|
|
782
|
-
|
|
410
|
+
keys
|
|
783
411
|
)
|
|
784
|
-
|
|
412
|
+
];
|
|
785
413
|
|
|
786
|
-
if (errorsFound.length
|
|
787
|
-
|
|
788
|
-
`delete item in dynamodb AwaitingMultipleStepByPending ==> awaitingStepId:${keyValues.awaitingStepId}`
|
|
789
|
-
);
|
|
790
|
-
promiseArray.push(
|
|
414
|
+
if (errorsFound.length === 0) {
|
|
415
|
+
promises.push(
|
|
791
416
|
dynamodbSharedLib.deleteItem(
|
|
792
417
|
_izContext,
|
|
793
418
|
dynamodbSharedLib.tableName(
|
|
794
419
|
_izContext,
|
|
795
420
|
'AwaitingMultipleStepByPending'
|
|
796
421
|
),
|
|
797
|
-
|
|
422
|
+
keys
|
|
798
423
|
)
|
|
799
424
|
);
|
|
800
425
|
}
|
|
801
|
-
await Promise.all(promiseArray);
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
/**
|
|
805
|
-
* Creates multiple awaiting steps with additional attributes and publishes corresponding messages to an SNS topic.
|
|
806
|
-
* Each message is augmented with a new `parentFlowId` representing its awaiting step before being published.
|
|
807
|
-
*
|
|
808
|
-
* @param {Object} _izContext - The execution context object containing logger and other utilities.
|
|
809
|
-
* @param {Array<Object>} messages - An array of messages to be augmented and published.
|
|
810
|
-
* @param {string} [prefix=''] - An optional prefix used when generating new awaiting step IDs.
|
|
811
|
-
* @param {Object} [flowType={}] - Defines the target SNS topic. Must contain `flowTag` and `serviceTag`.
|
|
812
|
-
* @param {string} flowType.flowTag - The flow tag identifier.
|
|
813
|
-
* @param {string} flowType.serviceTag - The service tag identifier.
|
|
814
|
-
* @param {Object} [additionalAttributes={}] - Additional attributes to save with each new awaiting step.
|
|
815
|
-
* @param {string} pendingStepId - The unique identifier of the parent pending step that waits for these new steps.
|
|
816
|
-
* @returns {Promise<void>} Resolves when all awaiting steps are created and messages are published.
|
|
817
|
-
* @throws {Error} Throws a NoRetryError if `messages` is not an array, or if `flowType` is missing `flowTag` or `serviceTag`.
|
|
818
|
-
*/
|
|
819
|
-
export async function createAwaitingMultipleStepsWithAdditionalAttributesAndPublish(
|
|
820
|
-
_izContext,
|
|
821
|
-
messages,
|
|
822
|
-
prefix = '',
|
|
823
|
-
flowType = {},
|
|
824
|
-
additionalAttributes = {},
|
|
825
|
-
pendingStepId
|
|
826
|
-
) {
|
|
827
|
-
_izContext.logger.debug(
|
|
828
|
-
'[Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish] Input parameters',
|
|
829
|
-
{
|
|
830
|
-
messages,
|
|
831
|
-
prefix,
|
|
832
|
-
flowType,
|
|
833
|
-
additionalAttributes,
|
|
834
|
-
pendingStepId
|
|
835
|
-
}
|
|
836
|
-
);
|
|
837
|
-
|
|
838
|
-
if (!Array.isArray(messages)) {
|
|
839
|
-
throw NoRetryError('messages must be an array');
|
|
840
|
-
}
|
|
841
426
|
|
|
842
|
-
|
|
843
|
-
const serviceTag = flowType.serviceTag;
|
|
844
|
-
|
|
845
|
-
if (flowTag === undefined || serviceTag === undefined) {
|
|
846
|
-
throw NoRetryError('flowType must have both flowTag and serviceTag');
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
const topicArn = snsSharedLib.snsTopicArnByFlowSchema(
|
|
850
|
-
_izContext,
|
|
851
|
-
flowType.flowTag,
|
|
852
|
-
flowType.serviceTag
|
|
853
|
-
);
|
|
854
|
-
|
|
855
|
-
_izContext.logger.debug(
|
|
856
|
-
'[Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish] Topic Arn',
|
|
857
|
-
topicArn
|
|
858
|
-
);
|
|
859
|
-
|
|
860
|
-
const messagesWithParentId = await Promise.all(
|
|
861
|
-
messages.map(async message => {
|
|
862
|
-
const parentFlowId = await createNewAwaitingMultipleStep(
|
|
863
|
-
_izContext,
|
|
864
|
-
pendingStepId,
|
|
865
|
-
prefix,
|
|
866
|
-
additionalAttributes
|
|
867
|
-
);
|
|
868
|
-
return {
|
|
869
|
-
...message,
|
|
870
|
-
parentFlowId
|
|
871
|
-
};
|
|
872
|
-
})
|
|
873
|
-
);
|
|
874
|
-
|
|
875
|
-
await Promise.all(
|
|
876
|
-
messagesWithParentId.map(message =>
|
|
877
|
-
sns.publishAsync(_izContext, {
|
|
878
|
-
TopicArn: `${topicArn}_In`,
|
|
879
|
-
Message: JSON.stringify(message),
|
|
880
|
-
MessageAttributes: {}
|
|
881
|
-
})
|
|
882
|
-
)
|
|
883
|
-
);
|
|
884
|
-
|
|
885
|
-
_izContext.logger.debug(
|
|
886
|
-
'[Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish] Exit point'
|
|
887
|
-
);
|
|
427
|
+
await Promise.all(promises);
|
|
888
428
|
}
|