@izara_project/izara-core-generate-service-code 1.0.97 → 1.0.99

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.
Files changed (56) hide show
  1. package/package.json +1 -1
  2. package/src/compile/flowValidator.js +45 -8
  3. package/src/compile/loadSchemas.js +26 -6
  4. package/src/emit/application/coreFunction/emitCoreFunctionArtifacts.js +15 -1
  5. package/src/emit/application/coreFunction/templates/InitialSetupConfig.ejs +8 -4
  6. package/src/emit/application/crud/templates/CreateEndpoint_Main.ejs +4 -4
  7. package/src/emit/application/crud/templates/CreateLogicalLib.ejs +60 -8
  8. package/src/emit/application/crud/templates/DeleteEndpoint_Main.ejs +4 -4
  9. package/src/emit/application/crud/templates/FlowEndpoint_HdrWbs.ejs +2 -2
  10. package/src/emit/application/crud/templates/FlowMain_Wbs.ejs +2 -2
  11. package/src/emit/application/crud/templates/UpdateEndpoint_Main.ejs +4 -4
  12. package/src/emit/application/custom/customFlowS3.js +4 -4
  13. package/src/emit/application/custom/templates/FlowEndpoint_Main.ejs +2 -2
  14. package/src/emit/application/custom/templates/s3/CreateObject_Main.ejs +5 -2
  15. package/src/emit/application/custom/templates/triggerCache/CheckTriggerCache_Main.ejs +2 -2
  16. package/src/emit/application/rbac/emitDynamicRbacFlowSchemas.js +4 -1
  17. package/src/emit/application/rbac/emitRbacApplicationArtifacts.js +76 -1
  18. package/src/emit/application/rbac/templates/ReservedDynamicUsage_Main.ejs +2 -0
  19. package/src/emit/application/rbac/templates/ReservedUsageTtlExpired_HdrDss.ejs +176 -0
  20. package/src/emit/application/relationship/templates/ChangeRelationship_Main.ejs +3 -2
  21. package/src/emit/application/relationship/templates/CreateRelationship_Main.ejs +3 -2
  22. package/src/emit/application/relationship/templates/DeleteRelationship_Main.ejs +3 -2
  23. package/src/emit/application/relationship/templates/GetRelationship_Main.ejs +3 -2
  24. package/src/emit/application/relationship/templates/MoveRelationship_Main.ejs +3 -2
  25. package/src/emit/application/relationship/templates/UpdateRelationship_Main.ejs +3 -2
  26. package/src/emit/application/system/templates/RegisterComplete_Main.ejs +6 -2
  27. package/src/emit/application/system/templates/Register_Main.ejs +6 -2
  28. package/src/emit/application/system/templates/WebSocketComplete_Main.ejs +3 -3
  29. package/src/emit/infrastructure/functions/functionYamlArtifact.js +28 -0
  30. package/src/emit/infrastructure/functions/templates/DssFunction_Yaml.ejs +21 -0
  31. package/src/emit/infrastructure/resources/iamResourceArtifacts.js +46 -6
  32. package/src/emit/infrastructure/resources/templates/GeneratedLambdaRoleServiceConfig.ejs +5 -3
  33. package/src/emit/schemas/attributeTree/emitAttributeTreeSchemas.js +75 -22
  34. package/src/emit/schemas/ledger/emitLedgerSchemas.js +33 -11
  35. package/src/emit/schemas/ledger/templates/LedgerObjectSchema.ejs +3 -0
  36. package/src/emit/schemas/ledger/templates/LedgerRelationshipSchema.ejs +1 -0
  37. package/src/emit/schemas/propertyValue/emitPropertyValueSchemas.js +329 -0
  38. package/src/generate.js +10 -73
  39. package/src/output/mergeHooks.js +169 -15
  40. package/src/plan/domainRegistry.js +31 -5
  41. package/task.md +76 -0
  42. package/test/integration/graphDrivenFlowSchema.test.js +58 -0
  43. package/test/integration/publicApi.test.js +54 -1
  44. package/test/unit/application/createTargetRoleHandler.test.js +70 -1
  45. package/test/unit/application/crudApplicationArtifacts.test.js +4 -0
  46. package/test/unit/application/customFlowApplicationArtifacts.test.js +9 -0
  47. package/test/unit/application/relationshipApplicationArtifacts.test.js +30 -0
  48. package/test/unit/infrastructure/resourceArtifacts.test.js +53 -0
  49. package/test/unit/output/mergeHooks.test.js +405 -0
  50. package/test/unit/schemas/attributeTreeSchemas.test.js +41 -63
  51. package/test/unit/schemas/attributeTreeSingleService.test.js +175 -0
  52. package/test/unit/schemas/ledgerSchemas.test.js +33 -7
  53. package/test/unit/schemas/propertyValueSchemas.test.js +265 -0
  54. package/test/unit/templates/hookTagsValidation.test.js +83 -0
  55. package/src/emit/schemas/attributeTree/emitAttributeTreeTargetSchemas.js +0 -153
  56. package/src/emit/schemas/attributeTree/resolveTargetServicePath.js +0 -111
@@ -3,6 +3,7 @@ import { readFile } from 'node:fs/promises';
3
3
 
4
4
  import {
5
5
  renderApiFunctionYaml,
6
+ renderDssFunctionYaml,
6
7
  renderInvFunctionYaml,
7
8
  renderSqsFunctionYaml,
8
9
  renderWbsFunctionYaml
@@ -53,7 +54,10 @@ export async function emitRbacApplicationArtifacts(objects) {
53
54
 
54
55
  const limitHandlers = await Promise.all(
55
56
  hasSelfRbac
56
- ? ACCOUNT_LIMIT_HANDLERS.map(createAccountLimitHandler)
57
+ ? [
58
+ ...ACCOUNT_LIMIT_HANDLERS.map(createAccountLimitHandler),
59
+ createReservedUsageTtlExpiredHandler()
60
+ ]
57
61
  : []
58
62
  );
59
63
 
@@ -173,9 +177,12 @@ const STATIC_LIMIT_APPLICATION_PATHS = [
173
177
  ...ACCOUNT_LIMIT_HANDLERS.flatMap((flowTag) => [
174
178
  `app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_Main.js`,
175
179
  `app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_HdrSqs.js`,
180
+ `app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_HdrInv.js`,
181
+ `app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_HdrApi.js`,
176
182
  `app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_WbsMain.js`,
177
183
  `app/src/generatedCode/FlowLimit/${flowTag}/source/${flowTag}_HdrWbs.js`
178
184
  ]),
185
+ 'app/src/generatedCode/FlowLimit/ReservedUsageTtlExpired/source/ReservedUsageTtlExpired_HdrDss.js',
179
186
  FLOW_LIMITS_YAML_PATH
180
187
  ];
181
188
 
@@ -210,6 +217,12 @@ async function createAccountLimitHandler(flowTag) {
210
217
  sourcePath,
211
218
  handlerPath
212
219
  );
220
+ const shared = {
221
+ flowTag,
222
+ flowStepName: '',
223
+ mainFileName: `${flowTag}_Main`,
224
+ functionName: flowTag
225
+ };
213
226
  return {
214
227
  artifacts: [
215
228
  {
@@ -220,6 +233,14 @@ async function createAccountLimitHandler(flowTag) {
220
233
  path: `${sourcePath}/${flowTag}_HdrSqs.js`,
221
234
  content: await renderRbacTemplate('ListRbac_HdrSqs.ejs', { flowTag })
222
235
  },
236
+ {
237
+ path: `${sourcePath}/${flowTag}_HdrInv.js`,
238
+ content: await renderSharedTemplate('FlowHandler_HdrInv.ejs', shared)
239
+ },
240
+ {
241
+ path: `${sourcePath}/${flowTag}_HdrApi.js`,
242
+ content: await renderSharedTemplate('FlowHandler_HdrApi.ejs', shared)
243
+ },
223
244
  ...webSocket.artifacts
224
245
  ],
225
246
  functions: [
@@ -232,11 +253,64 @@ async function createAccountLimitHandler(flowTag) {
232
253
  flowTag: flowTag,
233
254
  flowStepName: ''
234
255
  },
256
+ {
257
+ type: 'inv',
258
+ functionName: `${flowTag}HdrInv`,
259
+ handlerPath: `${handlerPath}/${flowTag}_HdrInv.main`,
260
+ roleName: 'FlowRbacRole',
261
+ flowTag: flowTag,
262
+ flowStepName: ''
263
+ },
264
+ {
265
+ type: 'api',
266
+ functionName: `${flowTag}HdrApi`,
267
+ handlerPath: `${handlerPath}/${flowTag}_HdrApi.main`,
268
+ roleName: 'FlowRbacRole',
269
+ flowTag: flowTag,
270
+ flowStepName: ''
271
+ },
235
272
  ...webSocket.functions
236
273
  ]
237
274
  };
238
275
  }
239
276
 
277
+ async function createReservedUsageTtlExpiredHandler() {
278
+ const sourcePath =
279
+ 'app/src/generatedCode/FlowLimit/ReservedUsageTtlExpired/source';
280
+ const handlerPath =
281
+ 'src/generatedCode/FlowLimit/ReservedUsageTtlExpired/source';
282
+ return {
283
+ artifacts: [
284
+ {
285
+ path: `${sourcePath}/ReservedUsageTtlExpired_HdrDss.js`,
286
+ content: await renderRbacTemplate('ReservedUsageTtlExpired_HdrDss.ejs')
287
+ }
288
+ ],
289
+ functions: [
290
+ {
291
+ type: 'dss',
292
+ functionName: 'ReservedUsageTtlExpiredHdrDss',
293
+ handlerPath: `${handlerPath}/ReservedUsageTtlExpired_HdrDss.main`,
294
+ roleName: 'FlowRbacRole',
295
+ tableName: 'RunningTotalReservedUsage',
296
+ batchSize: 100,
297
+ startingPosition: 'TRIM_HORIZON',
298
+ filterPatterns: [
299
+ {
300
+ eventName: ['REMOVE'],
301
+ userIdentity: {
302
+ type: ['Service'],
303
+ principalId: ['dynamodb.amazonaws.com']
304
+ }
305
+ }
306
+ ],
307
+ flowTag: 'ReservedUsageTtlExpired',
308
+ flowStepName: ''
309
+ }
310
+ ]
311
+ };
312
+ }
313
+
240
314
 
241
315
  async function createCustomRbacOwnTopicHandler(flowTag, mainTemplateName) {
242
316
  const sourcePath = `app/src/generatedCode/FlowRbac/${flowTag}/source`;
@@ -523,6 +597,7 @@ function renderFunctionYaml(descriptor) {
523
597
  if (descriptor.type === 'api') return renderApiFunctionYaml(descriptor);
524
598
  if (descriptor.type === 'inv') return renderInvFunctionYaml(descriptor);
525
599
  if (descriptor.type === 'wbs') return renderWbsFunctionYaml(descriptor);
600
+ if (descriptor.type === 'dss') return renderDssFunctionYaml(descriptor);
526
601
  return renderSqsFunctionYaml(descriptor);
527
602
  }
528
603
 
@@ -169,6 +169,8 @@ export default async function ReservedDynamicUsage(_izContext, requestParams) {
169
169
  {
170
170
  runningTotalReservedId: `${identifiersConcat}_${flowTypeConcat}`,
171
171
  usedTimestampId: uniqueIdentify,
172
+ identifiersConcat,
173
+ flowTypeConcat,
172
174
  usageCount: value,
173
175
  runningTotalUsageStatus: 'reserved',
174
176
  ttlTimestamp
@@ -0,0 +1,176 @@
1
+ /*
2
+ Copyright (C) 2020 Sven Mason <http://izara.io>
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU Affero General Public License as
6
+ published by the Free Software Foundation, either version 3 of the
7
+ License, or (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU Affero General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Affero General Public License
15
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ import { middlewareHandler as middleware } from '@izara_project/izara-middleware';
19
+ import Logger from '@izara_project/izara-core-library-logger';
20
+ import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
21
+
22
+ /**
23
+ * DynamoDB Stream handler for TTL expired records in RunningTotalReservedUsage.
24
+ * Automatically refunds abandoned reservations with atomic decrement.
25
+ */
26
+ export const main = middleware.wrap(async (event, context) => {
27
+ try {
28
+ if (!event || !Array.isArray(event.Records)) {
29
+ Logger.debug('No records in DynamoDB stream event');
30
+ return;
31
+ }
32
+
33
+ let _izContext = event._izContext;
34
+ if (!_izContext) {
35
+ _izContext = {
36
+ logger: Logger,
37
+ correlationIds: new Map()
38
+ };
39
+ }
40
+
41
+ for (const record of event.Records) {
42
+ let recordContext = record._izContext;
43
+ if (!recordContext) {
44
+ recordContext = _izContext;
45
+ }
46
+ let recordLogger = recordContext.logger;
47
+ if (!recordLogger) {
48
+ recordLogger = Logger;
49
+ }
50
+
51
+ const isTtlDelete =
52
+ record.eventName === 'REMOVE' &&
53
+ record.userIdentity &&
54
+ record.userIdentity.type === 'Service' &&
55
+ record.userIdentity.principalId === 'dynamodb.amazonaws.com';
56
+
57
+ if (!isTtlDelete) {
58
+ continue;
59
+ }
60
+
61
+ const oldImage = record.dynamodb && record.dynamodb.OldImage;
62
+ if (!oldImage) {
63
+ continue;
64
+ }
65
+
66
+ let oldStatus = null;
67
+ if (oldImage.runningTotalUsageStatus && oldImage.runningTotalUsageStatus.S) {
68
+ oldStatus = oldImage.runningTotalUsageStatus.S;
69
+ }
70
+
71
+ if (oldStatus !== 'reserved') {
72
+ continue;
73
+ }
74
+
75
+ let identifiersConcat = null;
76
+ if (oldImage.identifiersConcat && oldImage.identifiersConcat.S) {
77
+ identifiersConcat = oldImage.identifiersConcat.S;
78
+ }
79
+ let flowTypeConcat = null;
80
+ if (oldImage.flowTypeConcat && oldImage.flowTypeConcat.S) {
81
+ flowTypeConcat = oldImage.flowTypeConcat.S;
82
+ }
83
+
84
+ if ((!identifiersConcat || !flowTypeConcat) && oldImage.runningTotalReservedId && oldImage.runningTotalReservedId.S) {
85
+ const reservedId = oldImage.runningTotalReservedId.S;
86
+ const lastUnderscoreIndex = reservedId.lastIndexOf('_');
87
+ if (lastUnderscoreIndex > 0) {
88
+ if (!identifiersConcat) {
89
+ identifiersConcat = reservedId.substring(0, lastUnderscoreIndex);
90
+ }
91
+ if (!flowTypeConcat) {
92
+ flowTypeConcat = reservedId.substring(lastUnderscoreIndex + 1);
93
+ }
94
+ }
95
+ }
96
+
97
+ let usageCount = 1;
98
+ if (oldImage.usageCount && oldImage.usageCount.N) {
99
+ usageCount = Number(oldImage.usageCount.N);
100
+ }
101
+
102
+ if (identifiersConcat && flowTypeConcat && usageCount > 0) {
103
+ const usageTable = dynamodbSharedLib.tableName(
104
+ recordContext,
105
+ 'RunningTotalUsage'
106
+ );
107
+
108
+ const usageRecord = await dynamodbSharedLib.getItem(
109
+ recordContext,
110
+ usageTable,
111
+ {
112
+ identifiersConcat: identifiersConcat,
113
+ flowTypeConcat: flowTypeConcat
114
+ }
115
+ );
116
+
117
+ if (usageRecord) {
118
+ let currentTotal = 0;
119
+ if (typeof usageRecord.totalCount === 'number') {
120
+ currentTotal = usageRecord.totalCount;
121
+ }
122
+ const newTotal = Math.max(0, currentTotal - usageCount);
123
+ const updateUuid = recordContext.uniqueRequestId || `${Date.now()}`;
124
+
125
+ const queryElementsWhenUpdate = {
126
+ additionalAttributes: { currentUuid: usageRecord.updateUuid },
127
+ logicalElements: [
128
+ {
129
+ type: 'logical',
130
+ comparison: 'equals',
131
+ lhsAttribute: 'updateUuid',
132
+ rhsReference: 'currentUuid'
133
+ }
134
+ ],
135
+ returnValues: 'ALL_NEW'
136
+ };
137
+
138
+ const updateAttributes = [
139
+ { attributeName: 'totalCount', action: 'set', value: newTotal },
140
+ { attributeName: 'updateUuid', action: 'set', value: updateUuid }
141
+ ];
142
+
143
+ await dynamodbSharedLib.updateItem(
144
+ recordContext,
145
+ usageTable,
146
+ {
147
+ identifiersConcat: identifiersConcat,
148
+ flowTypeConcat: flowTypeConcat
149
+ },
150
+ updateAttributes,
151
+ queryElementsWhenUpdate,
152
+ {
153
+ complexAttributes: true,
154
+ errorOnConditionalExpNotPass: false
155
+ }
156
+ ).catch(() => null);
157
+
158
+ recordLogger.info({
159
+ message: '[ReservedUsageTtlExpired] Auto-refunded expired reservation',
160
+ identifiersConcat: identifiersConcat,
161
+ flowTypeConcat: flowTypeConcat,
162
+ usageCount: usageCount,
163
+ previousTotal: currentTotal,
164
+ newTotal: newTotal
165
+ });
166
+ }
167
+ }
168
+ }
169
+ } catch (err) {
170
+ Logger.error({
171
+ message: 'Unhandled error in ReservedUsageTtlExpired_HdrDss',
172
+ error: err
173
+ });
174
+ throw err;
175
+ }
176
+ });
@@ -29,14 +29,15 @@ import { sns } from '@izara_project/izara-core-library-external-request';
29
29
 
30
30
  import {
31
31
  getObjectSchema,
32
+ getRelSchema,
32
33
  utils,
33
34
  serviceConfig,
34
35
  consts,
35
36
  relSchemaLib
36
37
  } from '@izara_project/izara-core-library-service-schemas';
37
38
 
38
- const { getRelationshipSchemaWithCache, getObjSchemaS3WithHierarchy } =
39
- getObjectSchema;
39
+ const { getRelationshipSchemaWithCache } = getRelSchema;
40
+ const { getObjSchemaS3WithHierarchy } = getObjectSchema;
40
41
 
41
42
  const { createLinkTypeId } = utils;
42
43
 
@@ -29,6 +29,7 @@ import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
29
29
  import { sns } from '@izara_project/izara-core-library-external-request';
30
30
  import {
31
31
  getObjectSchema,
32
+ getRelSchema,
32
33
  utils,
33
34
  serviceConfig,
34
35
  consts,
@@ -36,8 +37,8 @@ import {
36
37
  identifiersObject
37
38
  } from '@izara_project/izara-core-library-service-schemas';
38
39
  const { findLinksByObjTypes } = relSchemaLib;
39
- const { getRelationshipSchemaWithCache, getObjSchemaS3WithHierarchy } =
40
- getObjectSchema;
40
+ const { getRelationshipSchemaWithCache } = getRelSchema;
41
+ const { getObjSchemaS3WithHierarchy } = getObjectSchema;
41
42
 
42
43
  const { createLinkTypeId } = utils;
43
44
 
@@ -29,14 +29,15 @@ import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
29
29
  import { sns } from '@izara_project/izara-core-library-external-request';
30
30
  import {
31
31
  getObjectSchema,
32
+ getRelSchema,
32
33
  utils,
33
34
  serviceConfig,
34
35
  consts,
35
36
  identifiersObject
36
37
  } from '@izara_project/izara-core-library-service-schemas';
37
38
 
38
- const { getRelationshipSchemaWithCache, getObjSchemaS3WithHierarchy } =
39
- getObjectSchema;
39
+ const { getRelationshipSchemaWithCache } = getRelSchema;
40
+ const { getObjSchemaS3WithHierarchy } = getObjectSchema;
40
41
 
41
42
  const { createLinkTypeId } = utils;
42
43
 
@@ -27,6 +27,7 @@ import {
27
27
  } from '@izara_project/izara-core-library-external-request';
28
28
  import {
29
29
  getObjectSchema,
30
+ getRelSchema,
30
31
  utils,
31
32
  serviceConfig,
32
33
  consts,
@@ -36,8 +37,8 @@ import {
36
37
  import { consts as coreConsts } from '@izara_project/izara-core-library-core';
37
38
 
38
39
  const { findLinksByObjTypes } = relSchemaLib;
39
- const { getRelationshipSchemaWithCache, getObjSchemaS3WithHierarchy } =
40
- getObjectSchema;
40
+ const { getRelationshipSchemaWithCache } = getRelSchema;
41
+ const { getObjSchemaS3WithHierarchy } = getObjectSchema;
41
42
  const { createLinkTypeId } = utils;
42
43
  const { getGraphServiceTagWithCache } = serviceConfig;
43
44
  const { PREFIX, TOPIC_NAME_GENERATE_CODE, TOPIC_NAME_GRAPH_HANDLER } = consts;
@@ -33,6 +33,7 @@ import {
33
33
 
34
34
  import {
35
35
  getObjectSchema,
36
+ getRelSchema,
36
37
  utils,
37
38
  serviceConfig,
38
39
  consts,
@@ -41,8 +42,8 @@ import {
41
42
  } from '@izara_project/izara-core-library-service-schemas';
42
43
  const { findLinksByObjTypes } = relSchemaLib;
43
44
 
44
- const { getRelationshipSchemaWithCache, getObjSchemaS3WithHierarchy } =
45
- getObjectSchema;
45
+ const { getRelationshipSchemaWithCache } = getRelSchema;
46
+ const { getObjSchemaS3WithHierarchy } = getObjectSchema;
46
47
 
47
48
  const { createLinkTypeId } = utils;
48
49
 
@@ -30,14 +30,15 @@ import { sns } from '@izara_project/izara-core-library-external-request';
30
30
 
31
31
  import {
32
32
  getObjectSchema,
33
+ getRelSchema,
33
34
  utils,
34
35
  serviceConfig,
35
36
  consts,
36
37
  identifiersObject
37
38
  } from '@izara_project/izara-core-library-service-schemas';
38
39
 
39
- const { getRelationshipSchemaWithCache, getObjSchemaS3WithHierarchy } =
40
- getObjectSchema;
40
+ const { getRelationshipSchemaWithCache } = getRelSchema;
41
+ const { getObjSchemaS3WithHierarchy } = getObjectSchema;
41
42
 
42
43
  const { createLinkTypeId } = utils;
43
44
 
@@ -1,6 +1,10 @@
1
1
  import { NoRetryError } from '@izara_project/izara-core-library-core';
2
2
  import { objectHash as hash } from '@izara_project/izara-shared-core';
3
- import { getObjectSchema, identifiersObject } from '@izara_project/izara-core-library-service-schemas';
3
+ import {
4
+ getObjectSchema,
5
+ getFlowSchema,
6
+ identifiersObject
7
+ } from '@izara_project/izara-core-library-service-schemas';
4
8
  import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
5
9
  import lambdaSharedLib from '@izara_project/izara-core-library-lambda';
6
10
  import { lambda, webSocket } from '@izara_project/izara-core-library-external-request';
@@ -29,7 +33,7 @@ export default async function registerCompleteMain(
29
33
  }
30
34
 
31
35
  let topicName = topicArn.split(':')[5].split('_');
32
- let flowSchema = await getObjectSchema.getFlowSchemaS3WithCache(_izContext, {
36
+ let flowSchema = await getFlowSchema.getFlowSchemaS3WithCache(_izContext, {
33
37
  flowTag: topicName[2],
34
38
  serviceTag: topicName[0]
35
39
  });
@@ -1,5 +1,9 @@
1
1
  import { objectHash as hash } from '@izara_project/izara-shared-core';
2
- import { getObjectSchema, identifiersObject } from '@izara_project/izara-core-library-service-schemas';
2
+ import {
3
+ getObjectSchema,
4
+ getFlowSchema,
5
+ identifiersObject
6
+ } from '@izara_project/izara-core-library-service-schemas';
3
7
  import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
4
8
  import lambdaSharedLib from '@izara_project/izara-core-library-lambda';
5
9
  import { lambda, webSocket } from '@izara_project/izara-core-library-external-request';
@@ -20,7 +24,7 @@ export default async function registerMain(
20
24
  ) {
21
25
  try {
22
26
  let connectionId = _izContext.correlationIds.get(consts.CONNECTION_ID);
23
- let flowSchema = await getObjectSchema.getFlowSchemaS3WithCache(_izContext, {
27
+ let flowSchema = await getFlowSchema.getFlowSchemaS3WithCache(_izContext, {
24
28
  flowTag: requestParams.flowTag,
25
29
  serviceTag: process.env.iz_serviceTag
26
30
  });
@@ -1,7 +1,7 @@
1
1
  import { NoRetryError } from '@izara_project/izara-core-library-core';
2
2
  import { consts } from '@izara_project/izara-middleware';
3
3
  import {
4
- getObjectSchema,
4
+ getFlowSchema,
5
5
  utils
6
6
  } from '@izara_project/izara-core-library-service-schemas';
7
7
  import dynamodbSharedLib from '@izara_project/izara-core-library-dynamodb';
@@ -30,7 +30,7 @@ export default async function WebSocketComplete(
30
30
  throw new NoRetryError('not have TopicArn for get FlowSchemas');
31
31
  const topicName = topicArn.split(':')[5].split('_');
32
32
  let flowTag = topicName[2];
33
- let flowSchema = await getObjectSchema.getFlowSchemaS3WithCache(
33
+ let flowSchema = await getFlowSchema.getFlowSchemaS3WithCache(
34
34
  _izContext,
35
35
  { flowTag, serviceTag: topicName[0] }
36
36
  );
@@ -40,7 +40,7 @@ export default async function WebSocketComplete(
40
40
  'Could not find flowSchema from topicArn or requestParams.flowTag'
41
41
  );
42
42
  flowTag = requestParams.flowTag;
43
- flowSchema = await getObjectSchema.getFlowSchemaS3WithCache(_izContext, {
43
+ flowSchema = await getFlowSchema.getFlowSchemaS3WithCache(_izContext, {
44
44
  flowTag,
45
45
  serviceTag: process.env.iz_serviceTag
46
46
  });
@@ -198,6 +198,34 @@ export function renderS3FunctionYaml({
198
198
  });
199
199
  }
200
200
 
201
+ export function renderDssFunctionYaml({
202
+ functionName,
203
+ handlerPath,
204
+ roleName,
205
+ tableName,
206
+ batchSize = 100,
207
+ startingPosition = 'TRIM_HORIZON',
208
+ filterPatterns = [],
209
+ flowTag,
210
+ flowStepName
211
+ }) {
212
+ return _renderFunctionTemplate('DssFunction_Yaml.ejs', {
213
+ functionName,
214
+ handlerPath,
215
+ roleName,
216
+ tableName,
217
+ batchSize,
218
+ startingPosition,
219
+ filterPatterns,
220
+ environmentSetting: _environmentSetting(
221
+ functionName,
222
+ flowTag,
223
+ flowStepName
224
+ ),
225
+ functionSetting: _functionSetting(functionName)
226
+ });
227
+ }
228
+
201
229
  export function renderEventBridgeFunctionYaml({
202
230
  functionName,
203
231
  handlerPath,
@@ -0,0 +1,21 @@
1
+ <%= functionName %>:
2
+ handler: <%= handlerPath %>
3
+ name: ${self:custom.iz_resourcePrefix}<%= functionName %>
4
+ role: <%= roleName %>
5
+ <%- environmentSetting %><%- functionSetting %>
6
+ events:
7
+ - stream:
8
+ type: dynamodb
9
+ arn:
10
+ Fn::GetAtt: [<%= tableName %>Table, StreamArn]
11
+ batchSize: <%= batchSize %>
12
+ startingPosition: <%= startingPosition %>
13
+ <% if (Array.isArray(filterPatterns) && filterPatterns.length > 0) { -%>
14
+ filterPatterns:
15
+ <% filterPatterns.forEach(function(pattern) { -%>
16
+ - eventName: <%- JSON.stringify(pattern.eventName) %>
17
+ userIdentity:
18
+ type: <%- JSON.stringify(pattern.userIdentity.type) %>
19
+ principalId: <%- JSON.stringify(pattern.userIdentity.principalId) %>
20
+ <% }); -%>
21
+ <% } -%>
@@ -96,9 +96,26 @@ export function getRbacValidatorServiceTags(state) {
96
96
  export async function renderLambdaRoleConfig(state) {
97
97
  const s3Flows = state.flows
98
98
  .filter((flow) => includesEvent(flow, 's3'))
99
- .map((flow) => ({
100
- roleName: upperFirst(flow.flowTag)
101
- }));
99
+ .map((flow) => {
100
+ let quotaServiceTag = flow.quotaServiceTag;
101
+ if (!quotaServiceTag && flow.belongTo) {
102
+ if (Array.isArray(flow.belongTo)) {
103
+ quotaServiceTag = flow.belongTo[0]?.serviceTag;
104
+ } else if (flow.belongTo.serviceTag) {
105
+ quotaServiceTag = flow.belongTo.serviceTag;
106
+ }
107
+ }
108
+ if (!quotaServiceTag && flow.objType?.serviceTag) {
109
+ quotaServiceTag = flow.objType.serviceTag;
110
+ }
111
+ if (!quotaServiceTag) {
112
+ quotaServiceTag = state.project?.serviceTag || 'Rbac';
113
+ }
114
+ return {
115
+ roleName: upperFirst(flow.flowTag),
116
+ quotaServiceTag
117
+ };
118
+ });
102
119
  const rbacValidatorServiceTags = getRbacValidatorServiceTags(state);
103
120
  return renderResourceTemplate('GeneratedLambdaRoleServiceConfig.ejs', {
104
121
  crud: state.crud,
@@ -160,6 +177,19 @@ export function roleStatements(state, roleName) {
160
177
  ]
161
178
  });
162
179
  }
180
+ if (roleName === 'FlowRbacRole' && state.selfRbac) {
181
+ statements.push({
182
+ action: [
183
+ 'dynamodb:DescribeStream',
184
+ 'dynamodb:GetRecords',
185
+ 'dynamodb:GetShardIterator',
186
+ 'dynamodb:ListStreams'
187
+ ],
188
+ resource: [
189
+ 'arn:aws:dynamodb:${self:custom.iz_region}:${self:custom.iz_accountId}:table/${self:custom.iz_resourcePrefix}RunningTotalReservedUsage/stream/*'
190
+ ]
191
+ });
192
+ }
163
193
  return statements;
164
194
  }
165
195
 
@@ -369,7 +399,7 @@ export function roleDlqQueueNames(state, roleName) {
369
399
  export function roleTopicNames(state, roleName) {
370
400
  if (roleName === 'ProcFindDataRole') {
371
401
  return state.outTopics
372
- .filter((topic) => topic === 'FindData')
402
+ .filter((topic) => topic === 'FindData' || topic === 'ProcessLogical')
373
403
  .map((t) => `${t}_Out`);
374
404
  }
375
405
  if (roleName === 'FlowObjectsRole') {
@@ -508,11 +538,16 @@ export function roleExternalTopicArns(state, roleName) {
508
538
  `arn:aws:sns:\${self:custom.iz_region}:\${self:custom.iz_accountId}:${tag}_\${self:custom.iz_stage}_ValidatorRbac_In`
509
539
  );
510
540
  if (roleName === 'FlowObjectsRole') {
541
+ const extraCrudTopics = extraTags.flatMap((tag) => [
542
+ `arn:aws:sns:\${self:custom.iz_region}:\${self:custom.iz_accountId}:${tag}_\${self:custom.iz_stage}_ValidatorRbac_In`,
543
+ `arn:aws:sns:\${self:custom.iz_region}:\${self:custom.iz_accountId}:${tag}_\${self:custom.iz_stage}_ConfirmUsage_In`,
544
+ `arn:aws:sns:\${self:custom.iz_region}:\${self:custom.iz_accountId}:${tag}_\${self:custom.iz_stage}_CancelUsage_In`
545
+ ]);
511
546
  return [
512
547
  `arn:aws:sns:\${self:custom.iz_region}:\${self:custom.iz_accountId}:Rbac_\${self:custom.iz_stage}_ValidatorRbac_In`,
513
548
  `arn:aws:sns:\${self:custom.iz_region}:\${self:custom.iz_accountId}:Rbac_\${self:custom.iz_stage}_ConfirmUsage_In`,
514
549
  `arn:aws:sns:\${self:custom.iz_region}:\${self:custom.iz_accountId}:Rbac_\${self:custom.iz_stage}_CancelUsage_In`,
515
- ...extraTopics
550
+ ...extraCrudTopics
516
551
  ];
517
552
  }
518
553
  if (roleName === 'FlowRbacRole' || roleName === 'FlowRelationshipRole') {
@@ -536,11 +571,16 @@ export function roleExternalLambdaArns(state, roleName) {
536
571
  `arn:aws:lambda:\${self:custom.iz_region}:\${self:custom.iz_accountId}:function:${tag}\${self:custom.iz_stage}ValidatorRbacHdrInv`
537
572
  );
538
573
  if (roleName === 'FlowObjectsRole') {
574
+ const extraCrudLambdas = extraTags.flatMap((tag) => [
575
+ `arn:aws:lambda:\${self:custom.iz_region}:\${self:custom.iz_accountId}:function:${tag}\${self:custom.iz_stage}ValidatorRbacHdrInv`,
576
+ `arn:aws:lambda:\${self:custom.iz_region}:\${self:custom.iz_accountId}:function:${tag}\${self:custom.iz_stage}ConfirmUsageHdrInv`,
577
+ `arn:aws:lambda:\${self:custom.iz_region}:\${self:custom.iz_accountId}:function:${tag}\${self:custom.iz_stage}CancelUsageHdrInv`
578
+ ]);
539
579
  return [
540
580
  `arn:aws:lambda:\${self:custom.iz_region}:\${self:custom.iz_accountId}:function:Rbac\${self:custom.iz_stage}ValidatorRbacHdrInv`,
541
581
  `arn:aws:lambda:\${self:custom.iz_region}:\${self:custom.iz_accountId}:function:Rbac\${self:custom.iz_stage}ConfirmUsageHdrInv`,
542
582
  `arn:aws:lambda:\${self:custom.iz_region}:\${self:custom.iz_accountId}:function:Rbac\${self:custom.iz_stage}CancelUsageHdrInv`,
543
- ...extraLambdas
583
+ ...extraCrudLambdas
544
584
  ];
545
585
  }
546
586
  if (roleName === 'FlowRbacRole' || roleName === 'FlowRelationshipRole') {