@izara_project/izara-core-library-asynchronous-flow 1.0.33 → 1.0.35
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/package.json +1 -1
- package/src/asyncFlowSharedLib.js +63 -16
- package/src/awaitingMultipleSteps.js +256 -73
- package/src/awaitingStep.js +83 -9
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"author": "Sven Mason <thebarbariansven@gmail.com>",
|
|
4
4
|
"license": "AGPL-3.0-or-later",
|
|
5
5
|
"homepage": "https://bitbucket.org/izara-core-libraries/izara-core-library-asynchronous-flow#readme",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.35",
|
|
7
7
|
"description": "Shared asynchronous flow logic",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "index.js",
|
|
@@ -105,6 +105,10 @@ export function createParentFlowId(prefix = '') {
|
|
|
105
105
|
* @throws {NoRetryError} If the stripped value equals the prefix (invalid)
|
|
106
106
|
*/
|
|
107
107
|
export function explodePendingStepId(pendingStepId, prefix = '') {
|
|
108
|
+
if (!pendingStepId) {
|
|
109
|
+
throw NoRetryError('pendingStepId is required');
|
|
110
|
+
}
|
|
111
|
+
|
|
108
112
|
if (prefix === '') {
|
|
109
113
|
return pendingStepId;
|
|
110
114
|
} else {
|
|
@@ -178,6 +182,22 @@ export async function checkUniqueRequestProcessing(
|
|
|
178
182
|
overwriteUniqueRequestId = null,
|
|
179
183
|
uniqueRequestIdFieldName = 'UniqueRequestId' // if set will check/add this fieldname with _izContext.uniqueRequestId value
|
|
180
184
|
) {
|
|
185
|
+
_izContext.logger.debug(
|
|
186
|
+
'[Lib:AsyncFlow:checkUniqueRequestProcessing] Input: ',
|
|
187
|
+
{
|
|
188
|
+
_izContext,
|
|
189
|
+
tableName,
|
|
190
|
+
primaryKey,
|
|
191
|
+
prefix,
|
|
192
|
+
overwriteUniqueRequestId,
|
|
193
|
+
uniqueRequestIdFieldName
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
if (!tableName || !primaryKey) {
|
|
198
|
+
throw NoRetryError('tableName and primaryKey are required');
|
|
199
|
+
}
|
|
200
|
+
|
|
181
201
|
try {
|
|
182
202
|
_izContext.logger.debug(
|
|
183
203
|
'current uniqueRequestId:',
|
|
@@ -298,6 +318,20 @@ export async function checkTimeCacheComplete(
|
|
|
298
318
|
timeCacheComplete,
|
|
299
319
|
prefix
|
|
300
320
|
) {
|
|
321
|
+
_izContext.logger.debug('[Lib:AsyncFlow:checkTimeCacheComplete] Input: ', {
|
|
322
|
+
_izContext,
|
|
323
|
+
fullMainTableName,
|
|
324
|
+
keyValues,
|
|
325
|
+
timeCacheComplete,
|
|
326
|
+
prefix
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
if (!fullMainTableName || !keyValues || !timeCacheComplete || !prefix) {
|
|
330
|
+
throw NoRetryError(
|
|
331
|
+
'fullMainTableName, keyValues, timeCacheComplete and prefix are required'
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
|
|
301
335
|
let [returnValue, newTimeCacheComplete, uniqueRequestId] =
|
|
302
336
|
await checkAndGetTimeCacheComplete(
|
|
303
337
|
_izContext,
|
|
@@ -329,16 +363,19 @@ export async function checkAndGetTimeCacheComplete(
|
|
|
329
363
|
timeCacheComplete,
|
|
330
364
|
prefix
|
|
331
365
|
) {
|
|
332
|
-
_izContext.logger.debug(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
366
|
+
_izContext.logger.debug(
|
|
367
|
+
'[Lib:AsyncFlow:checkAndGetTimeCacheComplete] Input: ',
|
|
368
|
+
{
|
|
369
|
+
fullMainTableName: fullMainTableName,
|
|
370
|
+
keyValues: keyValues,
|
|
371
|
+
timeCacheComplete: timeCacheComplete,
|
|
372
|
+
prefix: prefix
|
|
373
|
+
}
|
|
374
|
+
);
|
|
338
375
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
376
|
+
const uniqueRequestIdFieldName = createFieldNameUniqueRequestId('cache');
|
|
377
|
+
const cacheCompleteFieldName = createFieldNameCacheComplete(prefix);
|
|
378
|
+
const statusFieldName = createFieldNameStatus(prefix);
|
|
342
379
|
|
|
343
380
|
let getTimeCacheComplete = await dynamodbSharedLib.getItem(
|
|
344
381
|
_izContext,
|
|
@@ -436,6 +473,12 @@ export function validateStartKeyParam(
|
|
|
436
473
|
partitionKeyFieldName,
|
|
437
474
|
sortKeyFieldName
|
|
438
475
|
) {
|
|
476
|
+
_izContext.logger.debug('[Lib:AsyncFlow:validateStartKeyParam] Input: ', {
|
|
477
|
+
startKey,
|
|
478
|
+
partitionKeyFieldName,
|
|
479
|
+
sortKeyFieldName
|
|
480
|
+
});
|
|
481
|
+
|
|
439
482
|
const stringNotEmptyRegex = /^[A-Za-z0-9_-]+$/;
|
|
440
483
|
|
|
441
484
|
if (
|
|
@@ -482,12 +525,16 @@ export async function validateMultipleInvocations(
|
|
|
482
525
|
numberInvocation,
|
|
483
526
|
queueName
|
|
484
527
|
) {
|
|
485
|
-
_izContext.logger.debug(
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
528
|
+
_izContext.logger.debug(
|
|
529
|
+
'[Lib:AsyncFlow:validateMultipleInvocations] Input: ',
|
|
530
|
+
{
|
|
531
|
+
messageProperty: messageProperty,
|
|
532
|
+
passOnStartKey: passOnStartKey,
|
|
533
|
+
numberInvocation: numberInvocation,
|
|
534
|
+
queueName: queueName
|
|
535
|
+
}
|
|
536
|
+
);
|
|
537
|
+
|
|
491
538
|
try {
|
|
492
539
|
const maxProcessInvocationCountImport = 20;
|
|
493
540
|
if (numberInvocation >= maxProcessInvocationCountImport) {
|
|
@@ -504,7 +551,7 @@ export async function validateMultipleInvocations(
|
|
|
504
551
|
}
|
|
505
552
|
messageProperty['numberInvocation'] = numberInvocation;
|
|
506
553
|
|
|
507
|
-
|
|
554
|
+
const messageReInvokeFunction = {
|
|
508
555
|
MessageBody: JSON.stringify(messageProperty),
|
|
509
556
|
QueueUrl: await sqsSharedLib.sqsQueueUrl(_izContext, queueName)
|
|
510
557
|
};
|
|
@@ -43,16 +43,17 @@ export async function createAwaitingMultipleStepsWithAdditionalAttributes(
|
|
|
43
43
|
pendingStepId
|
|
44
44
|
) {
|
|
45
45
|
_izContext.logger.debug(
|
|
46
|
-
'Lib:createAwaitingMultipleStepsWithAdditionalAttributes',
|
|
46
|
+
'[Lib:AsyncFlow:createAwaitingMultipleStepsWithAdditionalAttributes] Input: ',
|
|
47
47
|
{
|
|
48
|
-
records
|
|
49
|
-
pendingStepId
|
|
48
|
+
records,
|
|
49
|
+
pendingStepId
|
|
50
50
|
}
|
|
51
51
|
);
|
|
52
|
-
let promiseArray = [];
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
const promiseArray = [];
|
|
54
|
+
|
|
55
|
+
for (const record of records) {
|
|
56
|
+
const attributesWhenCreate = {
|
|
56
57
|
awaitingStepId: record.awaitingStepId,
|
|
57
58
|
pendingStepId: pendingStepId,
|
|
58
59
|
timestamp: Date.now(),
|
|
@@ -101,10 +102,13 @@ export async function initAwaitingStepsWithAttrs(
|
|
|
101
102
|
records,
|
|
102
103
|
pendingStepId
|
|
103
104
|
) {
|
|
104
|
-
_izContext.logger.debug(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
_izContext.logger.debug(
|
|
106
|
+
'[Lib:AsyncFlow:initAwaitingStepsWithAttrs] Input: ',
|
|
107
|
+
{
|
|
108
|
+
records,
|
|
109
|
+
pendingStepId
|
|
110
|
+
}
|
|
111
|
+
);
|
|
108
112
|
|
|
109
113
|
const timestamp = Date.now();
|
|
110
114
|
const promiseArray = [];
|
|
@@ -155,22 +159,26 @@ export async function createAwaitingMultipleSteps(
|
|
|
155
159
|
records, // array of awaitingStepIds
|
|
156
160
|
pendingStepId
|
|
157
161
|
) {
|
|
158
|
-
_izContext.logger.debug(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
+
_izContext.logger.debug(
|
|
163
|
+
'[Lib:AsyncFlow:createAwaitingMultipleSteps] Input: ',
|
|
164
|
+
{
|
|
165
|
+
records: records,
|
|
166
|
+
pendingStepId: pendingStepId
|
|
167
|
+
}
|
|
168
|
+
);
|
|
162
169
|
|
|
163
|
-
|
|
170
|
+
const promiseArray = [];
|
|
164
171
|
|
|
165
|
-
for (
|
|
166
|
-
|
|
172
|
+
for (const record of records) {
|
|
173
|
+
const attributesWhenCreate = {
|
|
167
174
|
awaitingStepId: record,
|
|
168
175
|
pendingStepId: pendingStepId,
|
|
169
176
|
timestamp: Date.now()
|
|
170
177
|
};
|
|
171
|
-
_izContext.logger.debug(
|
|
172
|
-
|
|
173
|
-
|
|
178
|
+
_izContext.logger.debug(
|
|
179
|
+
'[Lib:AsyncFlow:createAwaitingMultipleSteps] attributesWhenCreate: ',
|
|
180
|
+
attributesWhenCreate
|
|
181
|
+
);
|
|
174
182
|
promiseArray.push(
|
|
175
183
|
dynamodbSharedLib.putItem(
|
|
176
184
|
_izContext,
|
|
@@ -179,9 +187,13 @@ export async function createAwaitingMultipleSteps(
|
|
|
179
187
|
)
|
|
180
188
|
);
|
|
181
189
|
|
|
182
|
-
_izContext.logger.debug(
|
|
183
|
-
|
|
184
|
-
|
|
190
|
+
_izContext.logger.debug(
|
|
191
|
+
'[Lib:AsyncFlow:createAwaitingMultipleSteps] putItem:AwaitingMultipleStepByPending',
|
|
192
|
+
{
|
|
193
|
+
awaitingStepId: attributesWhenCreate.awaitingStepId
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
|
|
185
197
|
promiseArray.push(
|
|
186
198
|
dynamodbSharedLib.putItem(
|
|
187
199
|
_izContext,
|
|
@@ -193,6 +205,7 @@ export async function createAwaitingMultipleSteps(
|
|
|
193
205
|
)
|
|
194
206
|
);
|
|
195
207
|
}
|
|
208
|
+
|
|
196
209
|
await Promise.all(promiseArray);
|
|
197
210
|
}
|
|
198
211
|
|
|
@@ -229,6 +242,11 @@ export async function createNewAwaitingMultipleStep(
|
|
|
229
242
|
errorsFound: []
|
|
230
243
|
};
|
|
231
244
|
|
|
245
|
+
_izContext.logger.debug(
|
|
246
|
+
'[Lib:AsyncFlow:createNewAwaitingMultipleStep] attributesWhenCreate: ',
|
|
247
|
+
attributesWhenCreate
|
|
248
|
+
);
|
|
249
|
+
|
|
232
250
|
await dynamodbSharedLib.putItem(
|
|
233
251
|
_izContext,
|
|
234
252
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
|
|
@@ -246,6 +264,11 @@ export async function createNewAwaitingMultipleStep(
|
|
|
246
264
|
attributesForPending
|
|
247
265
|
);
|
|
248
266
|
|
|
267
|
+
_izContext.logger.debug(
|
|
268
|
+
'[Lib:AsyncFlow:createNewAwaitingMultipleStep] Returning: ',
|
|
269
|
+
parentFlowId
|
|
270
|
+
);
|
|
271
|
+
|
|
249
272
|
return parentFlowId;
|
|
250
273
|
}
|
|
251
274
|
|
|
@@ -260,9 +283,23 @@ export async function findPendingStepIdsAwaitingMultipleSteps(
|
|
|
260
283
|
_izContext,
|
|
261
284
|
awaitingStepId
|
|
262
285
|
) {
|
|
263
|
-
|
|
286
|
+
_izContext.logger.debug(
|
|
287
|
+
'[Lib:findPendingStepIdsAwaitingMultipleSteps] Input parameters',
|
|
288
|
+
{
|
|
289
|
+
awaitingStepId: awaitingStepId
|
|
290
|
+
}
|
|
291
|
+
);
|
|
264
292
|
|
|
265
|
-
|
|
293
|
+
if (!awaitingStepId) {
|
|
294
|
+
_izContext.logger.error(
|
|
295
|
+
'[Lib:findPendingStepIdsAwaitingMultipleSteps] awaitingStepId is required'
|
|
296
|
+
);
|
|
297
|
+
throw new NoRetryError('awaitingStepId is required');
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const pendingStepIds = [];
|
|
301
|
+
|
|
302
|
+
const listPendingStepIds = await dynamodbSharedLib.query(
|
|
266
303
|
_izContext,
|
|
267
304
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
|
|
268
305
|
{
|
|
@@ -270,10 +307,15 @@ export async function findPendingStepIdsAwaitingMultipleSteps(
|
|
|
270
307
|
}
|
|
271
308
|
);
|
|
272
309
|
|
|
273
|
-
for (
|
|
274
|
-
pendingStepIds.push(
|
|
310
|
+
for (const item of listPendingStepIds.Items) {
|
|
311
|
+
pendingStepIds.push(item.pendingStepId);
|
|
275
312
|
}
|
|
276
313
|
|
|
314
|
+
_izContext.logger.debug(
|
|
315
|
+
'[Lib:findPendingStepIdsAwaitingMultipleSteps] Pending step IDs',
|
|
316
|
+
pendingStepIds
|
|
317
|
+
);
|
|
318
|
+
|
|
277
319
|
return pendingStepIds;
|
|
278
320
|
}
|
|
279
321
|
|
|
@@ -288,14 +330,33 @@ export async function findPendingStepsAwaitingMultipleSteps(
|
|
|
288
330
|
_izContext,
|
|
289
331
|
awaitingStepId
|
|
290
332
|
) {
|
|
291
|
-
|
|
333
|
+
_izContext.logger.debug(
|
|
334
|
+
'[Lib:findPendingStepsAwaitingMultipleSteps] Input parameters',
|
|
335
|
+
{
|
|
336
|
+
awaitingStepId: awaitingStepId
|
|
337
|
+
}
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
if (!awaitingStepId) {
|
|
341
|
+
_izContext.logger.error(
|
|
342
|
+
'[Lib:findPendingStepsAwaitingMultipleSteps] awaitingStepId is required'
|
|
343
|
+
);
|
|
344
|
+
throw new NoRetryError('awaitingStepId is required');
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const listPendingSteps = await dynamodbSharedLib.query(
|
|
292
348
|
_izContext,
|
|
293
349
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
|
|
294
350
|
{
|
|
295
351
|
awaitingStepId: awaitingStepId
|
|
296
352
|
}
|
|
297
353
|
);
|
|
298
|
-
|
|
354
|
+
|
|
355
|
+
_izContext.logger.debug(
|
|
356
|
+
'[Lib:findPendingStepsAwaitingMultipleSteps] Record of awaitingStepId',
|
|
357
|
+
listPendingSteps
|
|
358
|
+
);
|
|
359
|
+
|
|
299
360
|
return listPendingSteps.Items;
|
|
300
361
|
}
|
|
301
362
|
|
|
@@ -311,18 +372,40 @@ export async function findPendingStepAwaitingMultipleSteps(
|
|
|
311
372
|
_izContext,
|
|
312
373
|
awaitingStepId
|
|
313
374
|
) {
|
|
314
|
-
|
|
375
|
+
_izContext.logger.debug(
|
|
376
|
+
'[Lib:findPendingStepAwaitingMultipleSteps] Input parameters',
|
|
377
|
+
{
|
|
378
|
+
awaitingStepId: awaitingStepId
|
|
379
|
+
}
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
if (!awaitingStepId) {
|
|
383
|
+
_izContext.logger.error(
|
|
384
|
+
'[Lib:findPendingStepAwaitingMultipleSteps] awaitingStepId is required'
|
|
385
|
+
);
|
|
386
|
+
throw new NoRetryError('awaitingStepId is required');
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const listPendingSteps = await dynamodbSharedLib.query(
|
|
315
390
|
_izContext,
|
|
316
391
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleSteps'),
|
|
317
392
|
{
|
|
318
393
|
awaitingStepId: awaitingStepId
|
|
319
394
|
}
|
|
320
395
|
);
|
|
321
|
-
|
|
396
|
+
|
|
397
|
+
_izContext.logger.debug(
|
|
398
|
+
'[Lib:findPendingStepAwaitingMultipleSteps] Record of awaitingStepId',
|
|
399
|
+
listPendingSteps
|
|
400
|
+
);
|
|
322
401
|
|
|
323
402
|
if (listPendingSteps.Items.length !== 1) {
|
|
403
|
+
_izContext.logger.error(
|
|
404
|
+
'[Lib:findPendingStepAwaitingMultipleSteps] listPendingSteps not equals 1'
|
|
405
|
+
);
|
|
324
406
|
throw new NoRetryError('listPendingSteps not equals 1');
|
|
325
407
|
}
|
|
408
|
+
|
|
326
409
|
return listPendingSteps.Items[0];
|
|
327
410
|
}
|
|
328
411
|
|
|
@@ -343,7 +426,21 @@ export async function findAwaitingMultipleStepByPending(
|
|
|
343
426
|
_izContext,
|
|
344
427
|
pendingStepId
|
|
345
428
|
) {
|
|
346
|
-
|
|
429
|
+
_izContext.logger.debug(
|
|
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(
|
|
347
444
|
_izContext,
|
|
348
445
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleStepByPending'),
|
|
349
446
|
{
|
|
@@ -351,12 +448,24 @@ export async function findAwaitingMultipleStepByPending(
|
|
|
351
448
|
}
|
|
352
449
|
);
|
|
353
450
|
_izContext.logger.debug(
|
|
354
|
-
'Record of AwaitingMultipleStepByPending',
|
|
451
|
+
'[Lib:findAwaitingMultipleStepByPending] Record of AwaitingMultipleStepByPending',
|
|
355
452
|
listAwaitingSteps
|
|
356
453
|
);
|
|
454
|
+
|
|
357
455
|
return listAwaitingSteps.Items;
|
|
358
456
|
}
|
|
359
457
|
|
|
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
|
+
*/
|
|
360
469
|
export async function checkAllAwaitingStepsFinishedShared(
|
|
361
470
|
_izContext,
|
|
362
471
|
pendingStepId,
|
|
@@ -364,11 +473,14 @@ export async function checkAllAwaitingStepsFinishedShared(
|
|
|
364
473
|
errorsFound = [],
|
|
365
474
|
additionalAttributes = {}
|
|
366
475
|
) {
|
|
367
|
-
_izContext.logger.debug(
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
476
|
+
_izContext.logger.debug(
|
|
477
|
+
'[Lib:checkAllAwaitingStepsFinishedShared] Input parameters',
|
|
478
|
+
{
|
|
479
|
+
pendingStepId: pendingStepId,
|
|
480
|
+
currentAwaitingStepId: currentAwaitingStepId,
|
|
481
|
+
errorsFound: errorsFound
|
|
482
|
+
}
|
|
483
|
+
);
|
|
372
484
|
|
|
373
485
|
if (currentAwaitingStepId) {
|
|
374
486
|
await dynamodbSharedLib.updateItem(
|
|
@@ -381,7 +493,7 @@ export async function checkAllAwaitingStepsFinishedShared(
|
|
|
381
493
|
{
|
|
382
494
|
complete: true,
|
|
383
495
|
errorsFound: errorsFound,
|
|
384
|
-
|
|
496
|
+
additionalAttributes: additionalAttributes
|
|
385
497
|
}
|
|
386
498
|
);
|
|
387
499
|
}
|
|
@@ -404,6 +516,15 @@ export async function checkAllAwaitingStepsFinished(
|
|
|
404
516
|
errorsFound = [],
|
|
405
517
|
additionalAttributes = {}
|
|
406
518
|
) {
|
|
519
|
+
_izContext.logger.debug(
|
|
520
|
+
'[Lib:checkAllAwaitingStepsFinished] Input parameters',
|
|
521
|
+
{
|
|
522
|
+
pendingStepId: pendingStepId,
|
|
523
|
+
currentAwaitingStepId: currentAwaitingStepId,
|
|
524
|
+
errorsFound: errorsFound
|
|
525
|
+
}
|
|
526
|
+
);
|
|
527
|
+
|
|
407
528
|
await checkAllAwaitingStepsFinishedShared(
|
|
408
529
|
_izContext,
|
|
409
530
|
pendingStepId,
|
|
@@ -424,6 +545,9 @@ export async function checkAllAwaitingStepsFinished(
|
|
|
424
545
|
if (!item.complete) return false;
|
|
425
546
|
}
|
|
426
547
|
|
|
548
|
+
_izContext.logger.debug(
|
|
549
|
+
'[Lib:checkAllAwaitingStepsFinished] All steps are complete'
|
|
550
|
+
);
|
|
427
551
|
return true;
|
|
428
552
|
}
|
|
429
553
|
|
|
@@ -451,12 +575,21 @@ export async function checkAllAwaitingStepsFinishedWithReturnParams(
|
|
|
451
575
|
errorsFound = [],
|
|
452
576
|
additionalAttributes = {}
|
|
453
577
|
) {
|
|
454
|
-
_izContext.logger.debug(
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
578
|
+
_izContext.logger.debug(
|
|
579
|
+
'[Lib:checkAllAwaitingStepsFinishedWithReturnParams] Input parameters',
|
|
580
|
+
{
|
|
581
|
+
pendingStepId,
|
|
582
|
+
currentAwaitingStepId,
|
|
583
|
+
errorsFound,
|
|
584
|
+
additionalAttributes
|
|
585
|
+
}
|
|
586
|
+
);
|
|
587
|
+
|
|
588
|
+
if (!pendingStepId || !currentAwaitingStepId) {
|
|
589
|
+
throw NoRetryError(
|
|
590
|
+
'[Lib:checkAllAwaitingStepsFinishedWithReturnParams] pendingStepId or currentAwaitingStepId is required'
|
|
591
|
+
);
|
|
592
|
+
}
|
|
460
593
|
|
|
461
594
|
await checkAllAwaitingStepsFinishedShared(
|
|
462
595
|
_izContext,
|
|
@@ -473,7 +606,10 @@ export async function checkAllAwaitingStepsFinishedWithReturnParams(
|
|
|
473
606
|
{ limit: 50 }
|
|
474
607
|
);
|
|
475
608
|
|
|
476
|
-
_izContext.logger.debug(
|
|
609
|
+
_izContext.logger.debug(
|
|
610
|
+
'[Lib:checkAllAwaitingStepsFinishedWithReturnParams] awaitingStepItems:::',
|
|
611
|
+
awaitingStepItems
|
|
612
|
+
);
|
|
477
613
|
|
|
478
614
|
// Pass 1: check completeness of all other steps before collecting any data
|
|
479
615
|
for (const item of awaitingStepItems.Items) {
|
|
@@ -487,6 +623,10 @@ export async function checkAllAwaitingStepsFinishedWithReturnParams(
|
|
|
487
623
|
}
|
|
488
624
|
}
|
|
489
625
|
|
|
626
|
+
_izContext.logger.debug(
|
|
627
|
+
'[Lib:checkAllAwaitingStepsFinishedWithReturnParams] Pass 1: all steps are complete'
|
|
628
|
+
);
|
|
629
|
+
|
|
490
630
|
// Pass 2: all steps are complete — collect errors and attributes
|
|
491
631
|
const collectedAttributes = {};
|
|
492
632
|
const collectedErrors = [];
|
|
@@ -505,6 +645,10 @@ export async function checkAllAwaitingStepsFinishedWithReturnParams(
|
|
|
505
645
|
}
|
|
506
646
|
}
|
|
507
647
|
|
|
648
|
+
_izContext.logger.debug(
|
|
649
|
+
'[Lib:checkAllAwaitingStepsFinishedWithReturnParams] Pass 2: all steps are complete — collect errors and attributes'
|
|
650
|
+
);
|
|
651
|
+
|
|
508
652
|
return {
|
|
509
653
|
isComplete: true,
|
|
510
654
|
collectedAttributes,
|
|
@@ -521,17 +665,28 @@ export async function checkAllAwaitingStepsFinishedWithReturnParams(
|
|
|
521
665
|
* @returns {Promise<boolean>} true if delete flow processed
|
|
522
666
|
*/
|
|
523
667
|
export async function clearAllAwaitingSteps(_izContext, pendingStepId) {
|
|
668
|
+
_izContext.logger.debug('[Lib:clearAllAwaitingSteps] Input parameters', {
|
|
669
|
+
pendingStepId: pendingStepId
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
if (!pendingStepId) {
|
|
673
|
+
throw NoRetryError('[Lib:clearAllAwaitingSteps] pendingStepId is required');
|
|
674
|
+
}
|
|
675
|
+
|
|
524
676
|
// ----- query items from GSI table
|
|
525
|
-
|
|
677
|
+
const listPendingStepIds = await dynamodbSharedLib.query(
|
|
526
678
|
_izContext,
|
|
527
679
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingMultipleStepByPending'),
|
|
528
680
|
{
|
|
529
681
|
pendingStepId: pendingStepId
|
|
530
682
|
}
|
|
531
683
|
);
|
|
532
|
-
_izContext.logger.debug(
|
|
684
|
+
_izContext.logger.debug(
|
|
685
|
+
'[Lib:clearAllAwaitingSteps] listPendingStepIds',
|
|
686
|
+
listPendingStepIds
|
|
687
|
+
);
|
|
533
688
|
|
|
534
|
-
|
|
689
|
+
const promiseArray = [];
|
|
535
690
|
|
|
536
691
|
for (let idx = 0; idx < listPendingStepIds.Items.length; idx++) {
|
|
537
692
|
_izContext.logger.debug(`delete item in dynamodb AwaitingMultipleSteps`);
|
|
@@ -547,7 +702,7 @@ export async function clearAllAwaitingSteps(_izContext, pendingStepId) {
|
|
|
547
702
|
);
|
|
548
703
|
|
|
549
704
|
_izContext.logger.debug(
|
|
550
|
-
|
|
705
|
+
'[Lib:clearAllAwaitingSteps] delete item in dynamodb AwaitingMultipleStepByPending'
|
|
551
706
|
);
|
|
552
707
|
promiseArray.push(
|
|
553
708
|
dynamodbSharedLib.deleteItem(
|
|
@@ -585,19 +740,26 @@ export async function removeAwaitingMultipleStep(
|
|
|
585
740
|
pendingStepId,
|
|
586
741
|
errorsFound = []
|
|
587
742
|
) {
|
|
588
|
-
_izContext.logger.debug('Lib:removeAwaitingMultipleStep', {
|
|
743
|
+
_izContext.logger.debug('[Lib:removeAwaitingMultipleStep] Input parameters', {
|
|
589
744
|
awaitingStepId: awaitingStepId,
|
|
590
|
-
pendingStepId: pendingStepId
|
|
745
|
+
pendingStepId: pendingStepId,
|
|
746
|
+
errorsFound: errorsFound
|
|
591
747
|
});
|
|
592
748
|
|
|
593
|
-
|
|
749
|
+
if (!awaitingStepId || !pendingStepId) {
|
|
750
|
+
throw NoRetryError(
|
|
751
|
+
'[Lib:removeAwaitingMultipleStep] awaitingStepId or pendingStepId is required'
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
const promiseArray = [];
|
|
594
756
|
|
|
595
|
-
|
|
757
|
+
const keyValues = {
|
|
596
758
|
awaitingStepId: awaitingStepId,
|
|
597
759
|
pendingStepId: pendingStepId
|
|
598
760
|
};
|
|
599
761
|
|
|
600
|
-
|
|
762
|
+
const keyValuesForByPending = {
|
|
601
763
|
pendingStepId: pendingStepId,
|
|
602
764
|
awaitingStepId: awaitingStepId
|
|
603
765
|
};
|
|
@@ -607,7 +769,11 @@ export async function removeAwaitingMultipleStep(
|
|
|
607
769
|
});
|
|
608
770
|
|
|
609
771
|
_izContext.logger.debug(
|
|
610
|
-
|
|
772
|
+
'[Lib:removeAwaitingMultipleStep] delete item in dynamodb AwaitingMultipleSteps',
|
|
773
|
+
{
|
|
774
|
+
awaitingStepId: keyValues.awaitingStepId,
|
|
775
|
+
pendingStepId: keyValues.pendingStepId
|
|
776
|
+
}
|
|
611
777
|
);
|
|
612
778
|
promiseArray.push(
|
|
613
779
|
dynamodbSharedLib.deleteItem(
|
|
@@ -635,6 +801,21 @@ export async function removeAwaitingMultipleStep(
|
|
|
635
801
|
await Promise.all(promiseArray);
|
|
636
802
|
}
|
|
637
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
|
+
*/
|
|
638
819
|
export async function createAwaitingMultipleStepsWithAdditionalAttributesAndPublish(
|
|
639
820
|
_izContext,
|
|
640
821
|
messages,
|
|
@@ -643,30 +824,28 @@ export async function createAwaitingMultipleStepsWithAdditionalAttributesAndPubl
|
|
|
643
824
|
additionalAttributes = {},
|
|
644
825
|
pendingStepId
|
|
645
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
|
+
|
|
646
838
|
if (!Array.isArray(messages)) {
|
|
647
|
-
throw
|
|
839
|
+
throw NoRetryError('messages must be an array');
|
|
648
840
|
}
|
|
649
841
|
|
|
650
842
|
const flowTag = flowType.flowTag;
|
|
651
843
|
const serviceTag = flowType.serviceTag;
|
|
652
844
|
|
|
653
|
-
_izContext.logger.debug(
|
|
654
|
-
'[lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish] flowType',
|
|
655
|
-
{
|
|
656
|
-
flowTag,
|
|
657
|
-
serviceTag
|
|
658
|
-
}
|
|
659
|
-
);
|
|
660
|
-
|
|
661
845
|
if (flowTag === undefined || serviceTag === undefined) {
|
|
662
|
-
throw
|
|
846
|
+
throw NoRetryError('flowType must have both flowTag and serviceTag');
|
|
663
847
|
}
|
|
664
848
|
|
|
665
|
-
_izContext.logger.debug(
|
|
666
|
-
'Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish',
|
|
667
|
-
{ count: messages.length, pendingStepId, flowType }
|
|
668
|
-
);
|
|
669
|
-
|
|
670
849
|
const topicArn = snsSharedLib.snsTopicArnByFlowSchema(
|
|
671
850
|
_izContext,
|
|
672
851
|
flowType.flowTag,
|
|
@@ -674,8 +853,8 @@ export async function createAwaitingMultipleStepsWithAdditionalAttributesAndPubl
|
|
|
674
853
|
);
|
|
675
854
|
|
|
676
855
|
_izContext.logger.debug(
|
|
677
|
-
'Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish',
|
|
678
|
-
|
|
856
|
+
'[Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish] Topic Arn',
|
|
857
|
+
topicArn
|
|
679
858
|
);
|
|
680
859
|
|
|
681
860
|
const messagesWithParentId = await Promise.all(
|
|
@@ -702,4 +881,8 @@ export async function createAwaitingMultipleStepsWithAdditionalAttributesAndPubl
|
|
|
702
881
|
})
|
|
703
882
|
)
|
|
704
883
|
);
|
|
884
|
+
|
|
885
|
+
_izContext.logger.debug(
|
|
886
|
+
'[Lib:asyncFlow:createAwaitingMultipleStepsWithAdditionalAttributesAndPublish] Exit point'
|
|
887
|
+
);
|
|
705
888
|
}
|
package/src/awaitingStep.js
CHANGED
|
@@ -41,24 +41,25 @@ export async function createAwaitingStep(
|
|
|
41
41
|
additionalAttributes = {}, // save in top level
|
|
42
42
|
callingFlowConfig = {} // optional
|
|
43
43
|
) {
|
|
44
|
-
_izContext.logger.debug('Lib
|
|
44
|
+
_izContext.logger.debug('[Lib:AsyncFlow:createAwaitingStep] Input: ', {
|
|
45
45
|
awaitingStepId,
|
|
46
46
|
pendingStepId,
|
|
47
47
|
additionalAttributes,
|
|
48
48
|
callingFlowConfig
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
const attributesWhenCreate = {
|
|
52
52
|
awaitingStepId: awaitingStepId,
|
|
53
53
|
pendingStepId: pendingStepId,
|
|
54
54
|
timestamp: Date.now(),
|
|
55
55
|
uniqueRequestId: _izContext.uniqueRequestId
|
|
56
56
|
};
|
|
57
57
|
// loop if not empty
|
|
58
|
-
for (
|
|
58
|
+
for (const additionalAttribute in additionalAttributes) {
|
|
59
59
|
attributesWhenCreate[additionalAttribute] =
|
|
60
60
|
additionalAttributes[additionalAttribute]; // each additionalAttributes
|
|
61
61
|
}
|
|
62
|
+
|
|
62
63
|
if (Object.keys(callingFlowConfig).length > 0) {
|
|
63
64
|
Object.assign(attributesWhenCreate, { callingFlowConfig });
|
|
64
65
|
}
|
|
@@ -81,9 +82,20 @@ export async function findPendingStepIdsAwaitingStep(
|
|
|
81
82
|
_izContext,
|
|
82
83
|
awaitingStepId
|
|
83
84
|
) {
|
|
84
|
-
|
|
85
|
+
_izContext.logger.debug(
|
|
86
|
+
'[Lib:AsyncFlow:findPendingStepIdsAwaitingStep] Input: ',
|
|
87
|
+
{
|
|
88
|
+
awaitingStepId
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
if (!awaitingStepId) {
|
|
93
|
+
throw NoRetryError('awaitingStepId is required');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const pendingStepIds = [];
|
|
85
97
|
|
|
86
|
-
|
|
98
|
+
const listPendingStepIds = await dynamodbSharedLib.query(
|
|
87
99
|
_izContext,
|
|
88
100
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingStep'),
|
|
89
101
|
{
|
|
@@ -106,7 +118,18 @@ export async function findPendingStepIdsAwaitingStep(
|
|
|
106
118
|
* @returns {Promise<AwaitingStepItem[]>}
|
|
107
119
|
*/
|
|
108
120
|
export async function findPendingStepsAwaitingStep(_izContext, awaitingStepId) {
|
|
109
|
-
|
|
121
|
+
_izContext.logger.debug(
|
|
122
|
+
'[Lib:AsyncFlow:findPendingStepsAwaitingStep] Input: ',
|
|
123
|
+
{
|
|
124
|
+
awaitingStepId
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
if (!awaitingStepId) {
|
|
129
|
+
throw NoRetryError('awaitingStepId is required');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const listPendingSteps = await dynamodbSharedLib.query(
|
|
110
133
|
_izContext,
|
|
111
134
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingStep'),
|
|
112
135
|
{
|
|
@@ -126,17 +149,32 @@ export async function findPendingStepsAwaitingStep(_izContext, awaitingStepId) {
|
|
|
126
149
|
* @throws {NoRetryError} if there is not exactly one item
|
|
127
150
|
*/
|
|
128
151
|
export async function findPendingStepAwaitingStep(_izContext, awaitingStepId) {
|
|
129
|
-
|
|
152
|
+
_izContext.logger.debug(
|
|
153
|
+
'[Lib:AsyncFlow:findPendingStepAwaitingStep] Input: ',
|
|
154
|
+
{
|
|
155
|
+
awaitingStepId
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
if (!awaitingStepId) {
|
|
160
|
+
throw NoRetryError('awaitingStepId is required');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const listPendingSteps = await dynamodbSharedLib.query(
|
|
130
164
|
_izContext,
|
|
131
165
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingStep'),
|
|
132
166
|
{
|
|
133
167
|
awaitingStepId: awaitingStepId
|
|
134
168
|
}
|
|
135
169
|
);
|
|
136
|
-
|
|
170
|
+
|
|
171
|
+
_izContext.logger.debug(
|
|
172
|
+
'[Lib:AsyncFlow:findPendingStepAwaitingStep] Found records: ',
|
|
173
|
+
listPendingSteps
|
|
174
|
+
);
|
|
137
175
|
|
|
138
176
|
if (listPendingSteps.Items.length !== 1) {
|
|
139
|
-
throw
|
|
177
|
+
throw NoRetryError('listPendingSteps not equals 1');
|
|
140
178
|
}
|
|
141
179
|
return listPendingSteps.Items[0];
|
|
142
180
|
}
|
|
@@ -154,6 +192,17 @@ export async function findPendingStepAwaitingStepWithCallingFlow(
|
|
|
154
192
|
_izContext,
|
|
155
193
|
awaitingStepId
|
|
156
194
|
) {
|
|
195
|
+
_izContext.logger.debug(
|
|
196
|
+
'[Lib:AsyncFlow:findPendingStepAwaitingStepWithCallingFlow] Input: ',
|
|
197
|
+
{
|
|
198
|
+
awaitingStepId
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
if (!awaitingStepId) {
|
|
203
|
+
throw NoRetryError('awaitingStepId is required');
|
|
204
|
+
}
|
|
205
|
+
|
|
157
206
|
let callingFlowConfig = null;
|
|
158
207
|
let awaitingStep = await findPendingStepAwaitingStep(
|
|
159
208
|
_izContext,
|
|
@@ -184,6 +233,15 @@ export async function removeAwaitingStep(
|
|
|
184
233
|
awaitingStepId,
|
|
185
234
|
pendingStepId
|
|
186
235
|
) {
|
|
236
|
+
_izContext.logger.debug('[Lib:AsyncFlow:removeAwaitingStep] Input: ', {
|
|
237
|
+
awaitingStepId,
|
|
238
|
+
pendingStepId
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
if (!awaitingStepId || !pendingStepId) {
|
|
242
|
+
throw NoRetryError('awaitingStepId and pendingStepId are required');
|
|
243
|
+
}
|
|
244
|
+
|
|
187
245
|
await dynamodbSharedLib.deleteItem(
|
|
188
246
|
_izContext,
|
|
189
247
|
dynamodbSharedLib.tableName(_izContext, 'AwaitingStep'),
|
|
@@ -213,6 +271,22 @@ export async function removeAwaitingStepWithCheckUniqueRequestId(
|
|
|
213
271
|
checkUniqueRequestId,
|
|
214
272
|
prefix = ''
|
|
215
273
|
) {
|
|
274
|
+
_izContext.logger.debug(
|
|
275
|
+
'[Lib:AsyncFlow:removeAwaitingStepWithCheckUniqueRequestId] Input: ',
|
|
276
|
+
{
|
|
277
|
+
awaitingStepId,
|
|
278
|
+
pendingStepId,
|
|
279
|
+
checkUniqueRequestId,
|
|
280
|
+
prefix
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
if (!awaitingStepId || !pendingStepId || !checkUniqueRequestId) {
|
|
285
|
+
throw NoRetryError(
|
|
286
|
+
'awaitingStepId, pendingStepId and checkUniqueRequestId are required'
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
216
290
|
// if logicalElements add queryElements.logicalElements
|
|
217
291
|
// set condition uniqueRequestId match with exists
|
|
218
292
|
const queryElementsCondition = {
|