@izara_project/izara-market-library-service-schemas 1.0.74 → 1.0.76
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 +10 -6
- package/package.json +7 -5
- package/src/CheckPermission/CheckPermission.js +148 -0
- package/src/GenerateCodeLibs/src/Consts.js +6 -2
- package/src/GenerateCodeLibs/src/GenerateCodeLibs.js +359 -4
- package/src/reStructure/TemplateData/EndpointPerService/mainFunction/get/template.ejs +12 -10
- package/src/reStructure/TemplateData/EndpointPerService/mainFunction/update/template.ejs +10 -7
package/index.js
CHANGED
|
@@ -17,14 +17,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
17
17
|
|
|
18
18
|
'use strict';
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
20
|
module.exports = {
|
|
23
21
|
templateMgr: require('./src/TemplateManager'),
|
|
24
22
|
sourceMgr: require('./src/SourceManager'),
|
|
25
23
|
generateCodeLibs: require('./src/GenerateCodeLibs'),
|
|
26
24
|
utils: require('./src/MainLibs'),
|
|
27
|
-
generateSchemaWithTemplate:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
generateSchemaWithTemplate:
|
|
26
|
+
require('./src/TemplateManager/src/GenerateSchema')
|
|
27
|
+
.generateSchemaWithTemplate,
|
|
28
|
+
generateCodeWithTemplate: require('./src/reStructure/GenerateCode')
|
|
29
|
+
.generateCodeWithTemplate,
|
|
30
|
+
generateSchema: require('./src/reStructure/GenerateSchema'),
|
|
31
|
+
|
|
32
|
+
// Libs
|
|
33
|
+
checkPermission: require('./src/CheckPermission/CheckPermission')
|
|
34
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@izara_project/izara-market-library-service-schemas",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.76",
|
|
4
4
|
"description": "Schemas for Izara Market project",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"license": "AGPL-3.0-or-later",
|
|
15
15
|
"homepage": "https://bitbucket.org/izara-market-libraries/izara-market-library-service-schemas/src/master/README.md",
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"jest": "^30.0
|
|
17
|
+
"jest": "^30.2.0"
|
|
18
18
|
},
|
|
19
19
|
"jest": {
|
|
20
20
|
"testEnvironment": "node"
|
|
@@ -22,18 +22,20 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@izara_project/izara-core-library-calling-flow": "^1.0.3",
|
|
24
24
|
"@izara_project/izara-core-library-core": "^1.0.20",
|
|
25
|
+
"@izara_project/izara-core-library-dynamodb": "^1.0.11",
|
|
25
26
|
"@izara_project/izara-core-library-external-request": "^1.0.20",
|
|
27
|
+
"@izara_project/izara-core-library-lambda": "^1.0.5",
|
|
26
28
|
"@izara_project/izara-core-library-logger": "^1.0.7",
|
|
27
|
-
"@izara_project/izara-core-library-service-schemas": "^1.0.
|
|
29
|
+
"@izara_project/izara-core-library-service-schemas": "^1.0.100",
|
|
28
30
|
"@izara_project/izara-core-library-sns": "^1.0.6",
|
|
29
31
|
"@izara_project/izara-core-library-sqs": "^1.0.4",
|
|
30
32
|
"@izara_project/izara-shared": "^1.0.126",
|
|
31
|
-
"@izara_project/izara-shared-service-schemas": "^1.0.31",
|
|
32
33
|
"@izara_project/izara-shared-core": "^1.0.2",
|
|
34
|
+
"@izara_project/izara-shared-service-schemas": "^1.0.31",
|
|
33
35
|
"ejs": "^3.1.10",
|
|
34
36
|
"js-beautify": "^1.15.4",
|
|
35
37
|
"lodash": "^4.17.21",
|
|
36
38
|
"object-hash": "^3.0.0",
|
|
37
|
-
"yaml": "^2.8.
|
|
39
|
+
"yaml": "^2.8.1"
|
|
38
40
|
}
|
|
39
41
|
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2021 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
|
+
/*
|
|
19
|
+
Copyright (C) 2020 Sven Mason <http://izara.io>
|
|
20
|
+
|
|
21
|
+
This program is free software: you can redistribute it and/or modify
|
|
22
|
+
it under the terms of the GNU Affero General Public License as
|
|
23
|
+
published by the Free Software Foundation, either version 3 of the
|
|
24
|
+
License, or (at your option) any later version.
|
|
25
|
+
|
|
26
|
+
This program is distributed in the hope that it will be useful,
|
|
27
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
28
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
29
|
+
GNU Affero General Public License for more details.
|
|
30
|
+
|
|
31
|
+
You should have received a copy of the GNU Affero General Public License
|
|
32
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
'use strict';
|
|
36
|
+
|
|
37
|
+
const {
|
|
38
|
+
lambdaFunctionName
|
|
39
|
+
} = require('@izara_project/izara-core-library-lambda');
|
|
40
|
+
const {
|
|
41
|
+
lambda: { invokeSync }
|
|
42
|
+
} = require('@izara_project/izara-core-library-external-request');
|
|
43
|
+
const { consts } = require('@izara_project/izara-core-library-core');
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Checks a user's permission by invoking another Lambda function.
|
|
47
|
+
* Adheres to Izara.io backend syntax guidelines.
|
|
48
|
+
*
|
|
49
|
+
* @param {object} _izContext - The context object containing logger, credentials, etc.
|
|
50
|
+
* @param {object} payload - The data payload for the permission check.
|
|
51
|
+
* @param {string} [payload.objectType] - The type of the object (e.g., 'INVOICE'). Must be used with `action`.
|
|
52
|
+
* @param {string} [payload.action] - The action to perform (e.g., 'READ', 'APPROVE'). Must be used with `objectType`.
|
|
53
|
+
* @param {string} [payload.flowTag] - The tag for a flow-based permission check. Used instead of `objectType`/`action`.
|
|
54
|
+
* @param {string} [payload.serviceName] - The name of the calling service (optional).
|
|
55
|
+
* @returns {Promise<{status: boolean, errorFound?: string}>}
|
|
56
|
+
* Resolves with the result of the permission check:
|
|
57
|
+
* - `status`: Whether the user has permission.
|
|
58
|
+
* - `errorFound`: Optional error message if the permission check failed.
|
|
59
|
+
*
|
|
60
|
+
* @throws {Error} If the payload is invalid or Lambda invocation fails.
|
|
61
|
+
*/
|
|
62
|
+
async function checkPermission(_izContext, payload) {
|
|
63
|
+
// Validate that the payload object itself is provided.
|
|
64
|
+
if (!payload || typeof payload !== 'object') {
|
|
65
|
+
const error = new Error('Payload object is required.');
|
|
66
|
+
_izContext.logger.error(error.message);
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const userId = _izContext.correlationIds.get(consts.BASE_USER_ID);
|
|
71
|
+
const targetId = _izContext.correlationIds.get(consts.TARGET_ID);
|
|
72
|
+
|
|
73
|
+
// Validate the required 'userId' field.
|
|
74
|
+
if (!userId || typeof userId !== 'string' || userId.trim() === '') {
|
|
75
|
+
const error = new Error(
|
|
76
|
+
'userId is required and must be a non-empty string.'
|
|
77
|
+
);
|
|
78
|
+
_izContext.logger.error(error.message);
|
|
79
|
+
throw error;
|
|
80
|
+
} else {
|
|
81
|
+
payload.userId = userId;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (targetId) {
|
|
85
|
+
payload.targetId = targetId;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Define validation flags for business rules.
|
|
89
|
+
const hasObjectParams = payload.objectType || payload.action;
|
|
90
|
+
const hasFlowTag = payload.flowTag;
|
|
91
|
+
|
|
92
|
+
// Rule: Cannot mix object-based and flow-based parameters.
|
|
93
|
+
if (hasObjectParams && hasFlowTag) {
|
|
94
|
+
const error = new Error(
|
|
95
|
+
'Invalid payload: Cannot provide flowTag together with objectType or action.'
|
|
96
|
+
);
|
|
97
|
+
_izContext.logger.error(error.message, { payload });
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Rule: If using object-based, both objectType and action are required.
|
|
102
|
+
if (hasObjectParams && (!payload.objectType || !payload.action)) {
|
|
103
|
+
const error = new Error(
|
|
104
|
+
'Invalid payload: Both objectType and action must be provided together.'
|
|
105
|
+
);
|
|
106
|
+
_izContext.logger.error(error.message, { payload });
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Rule: Must provide at least one of the two valid schemas.
|
|
111
|
+
if (!hasObjectParams && !hasFlowTag) {
|
|
112
|
+
const error = new Error(
|
|
113
|
+
'Invalid payload: Must provide either (objectType and action) or flowTag.'
|
|
114
|
+
);
|
|
115
|
+
_izContext.logger.error(error.message, { payload });
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Log the payload for debugging before invoking the next service.
|
|
120
|
+
_izContext.logger.debug('Checking permission with payload:', payload);
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const lambdaName = await lambdaFunctionName(
|
|
124
|
+
_izContext,
|
|
125
|
+
'CheckPermissionHdrInv',
|
|
126
|
+
'UserAccount'
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const result = await invokeSync(_izContext, lambdaName, payload);
|
|
130
|
+
|
|
131
|
+
_izContext.logger.info('Permission check invoked successfully.');
|
|
132
|
+
|
|
133
|
+
// example result = { status: boolean , errorFound: string }
|
|
134
|
+
return result;
|
|
135
|
+
|
|
136
|
+
} catch (err) {
|
|
137
|
+
// Log the full error object for better traceability.
|
|
138
|
+
_izContext.logger.error(
|
|
139
|
+
'Error invoking CheckPermissionHdrInv Lambda: ',
|
|
140
|
+
err
|
|
141
|
+
);
|
|
142
|
+
throw err;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
module.exports = {
|
|
147
|
+
checkPermission
|
|
148
|
+
};
|
|
@@ -26,7 +26,12 @@ const PREFIX = {
|
|
|
26
26
|
updateNode: "updateNodeEndpoint",
|
|
27
27
|
createNode: "createNodeEndpoint",
|
|
28
28
|
getRel: "getRelationshipEndpoint",
|
|
29
|
-
changeRel: "changeRelationshipEndpoint"
|
|
29
|
+
changeRel: "changeRelationshipEndpoint",
|
|
30
|
+
ONE: "one",
|
|
31
|
+
MANY: "many",
|
|
32
|
+
CREATE_OBJECT_ASYNC: "createObjectAsync",
|
|
33
|
+
CREATE_OBJECT_ASYNC_COMPLETE: "createObjectAsyncComplete",
|
|
34
|
+
CREATE_OBJECT_EXTERNAL_TOPIC: "createObjectExternalTopic",
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
// const TOPIC_NAME_GRAPH_HANDLER = {
|
|
@@ -119,7 +124,6 @@ const EXTERNAL_SERVICE_NAME = {
|
|
|
119
124
|
accountLimits: "AccountLimits"
|
|
120
125
|
}
|
|
121
126
|
|
|
122
|
-
|
|
123
127
|
module.exports = {
|
|
124
128
|
TOPIC_NAME_GENERATE_CODE,
|
|
125
129
|
TOPIC_NAME_GRAPH_HANDLER,
|
|
@@ -19,10 +19,7 @@ along with this program.If not, see < http://www.gnu.org/licenses/>.
|
|
|
19
19
|
|
|
20
20
|
const lodash = require('lodash');
|
|
21
21
|
const hash = require('@izara_project/izara-shared-core').objectHash;
|
|
22
|
-
const snsSharedLib = require('@izara_project/izara-core-library-sns');
|
|
23
|
-
const sqsSharedLib = require('@izara_project/izara-core-library-sqs');
|
|
24
22
|
const inMemoryCacheLib = require('@izara_project/izara-core-library-core').inMemoryCacheLib;
|
|
25
|
-
const callingFlowSharedLib = require('@izara_project/izara-core-library-calling-flow');
|
|
26
23
|
const sns = require('@izara_project/izara-core-library-external-request/src/resources/Sns');
|
|
27
24
|
const sqs = require('@izara_project/izara-core-library-external-request/src/resources/Sqs');
|
|
28
25
|
const NoRetryError = require('@izara_project/izara-core-library-core/src/NoRetryError');
|
|
@@ -42,6 +39,20 @@ const nodeLabelRegexPattern = "^[a-zA-Z0-9_-]+(?:\:[a-zA-Z0-9_-]+)?$"
|
|
|
42
39
|
const { validateObjType } = require('@izara_project/izara-shared-service-schemas').validateObjType;
|
|
43
40
|
// const { validateObject } = require('@izara_project/izara-core-library-core').validator
|
|
44
41
|
const { validateObject } = require("@izara_project/izara-core-library-core").validator
|
|
42
|
+
// core libs
|
|
43
|
+
const dynamodbSharedLib = require('@izara_project/izara-core-library-dynamodb');
|
|
44
|
+
const asyncFlowSharedLib = require('@izara_project/izara-core-library-asynchronous-flow')
|
|
45
|
+
const callingFlowSharedLib = require('@izara_project/izara-core-library-calling-flow');
|
|
46
|
+
const sqsSharedLib = require('@izara_project/izara-core-library-sqs');
|
|
47
|
+
const snsSharedLib = require('@izara_project/izara-core-library-sns');
|
|
48
|
+
const graphSharedLibs = require('@izara_project/izara-core-library-graph-service');
|
|
49
|
+
const lambdaSharedLib = require('@izara_project/izara-core-library-lambda')
|
|
50
|
+
const {
|
|
51
|
+
TOPIC_NAME_GENERATE_CODE,
|
|
52
|
+
TOPIC_NAME_GRAPH_HANDLER,
|
|
53
|
+
GRAPH_HANDLER_SERVICE_NAME,
|
|
54
|
+
} = require('@izara_project/izara-market-library-service-schemas/src/GenerateCodeLibs/src/Consts');
|
|
55
|
+
const { PREFIX } = require('./Consts')
|
|
45
56
|
|
|
46
57
|
const schemaFunctionPerAction = {
|
|
47
58
|
[consts.ACTIONS.create]: validatorSchema.generateValidatorSchemaForCreate,
|
|
@@ -1090,6 +1101,348 @@ function createFieldNamesFromRequestParamsByObjectSchema(_izContext, requestPara
|
|
|
1090
1101
|
return createFieldNameParams
|
|
1091
1102
|
}
|
|
1092
1103
|
|
|
1104
|
+
async function sharedCreateEndpoint(_izContext, objType, requestParams, callingFlowConfig, settings = { userAgent: false, directInvoke: false, parentObject }) {
|
|
1105
|
+
let objectSchemas = await getObjectSchema.getObjectSchemaCombineFieldNamesWithCache(_izContext, objType)
|
|
1106
|
+
let createDataDetails = await createDataDetailsLib(_izContext, objectSchemas)
|
|
1107
|
+
_izContext.logger.debug("createDataDetails is =", createDataDetails);
|
|
1108
|
+
let listOfObjectForCreates = [];
|
|
1109
|
+
let allAwaitingStepsId = [];
|
|
1110
|
+
|
|
1111
|
+
let objInstanceFull = {
|
|
1112
|
+
identifiers: {},
|
|
1113
|
+
fields: {}
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
for (let fieldName of Object.keys(requestParams.fieldNames)) {
|
|
1117
|
+
if (objectSchemas.identifierFieldNames.includes(fieldName)) {
|
|
1118
|
+
_izContext.logger.debug("identifiers is", fieldName);
|
|
1119
|
+
Object.assign(objInstanceFull.identifiers, {
|
|
1120
|
+
[fieldName]: requestParams.fieldNames[fieldName]
|
|
1121
|
+
});
|
|
1122
|
+
};
|
|
1123
|
+
};
|
|
1124
|
+
|
|
1125
|
+
let objInstanceFullForDynamoDb = lodash.cloneDeep(objInstanceFull);
|
|
1126
|
+
let objInstanceFullForGraph = lodash.cloneDeep(objInstanceFull);
|
|
1127
|
+
let objInstanceFullForExternalTopic = lodash.cloneDeep(objInstanceFull);
|
|
1128
|
+
|
|
1129
|
+
for (const [storageTag, createDataDetail] of Object.entries(createDataDetails)) {
|
|
1130
|
+
if (createDataDetail.storageType == consts.STORAGE_TYPES.dynamoDB) {
|
|
1131
|
+
_izContext.logger.debug("::::::DynamoDB::::::", { storageTag, objInstanceFull });
|
|
1132
|
+
|
|
1133
|
+
if (settings.parentObject) {
|
|
1134
|
+
if (createDataDetail.tableName.includes(firstLetterUpperCase(`${parentObject.objectType}Records`))) {
|
|
1135
|
+
Object.assign(
|
|
1136
|
+
objInstanceFullForDynamoDb.fields, {
|
|
1137
|
+
[`${settings.parentObject.objectType}HandlerServiceTag`]: process.env.iz_serviceTag
|
|
1138
|
+
})
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
Object.assign(objInstanceFullForDynamoDb.fields, createObjInstanceFullFieldsByStorageTag(_izContext, storageTag, createDataDetail))
|
|
1143
|
+
_izContext.logger.debug("objInstanceFull before create item in dynamoDB", objInstanceFullForDynamoDb)
|
|
1144
|
+
|
|
1145
|
+
let identifiersForCreateData = await dynamoDbIdentifiersByStorageResource(
|
|
1146
|
+
_izContext,
|
|
1147
|
+
objectSchemas,
|
|
1148
|
+
createDataDetail,
|
|
1149
|
+
objInstanceFullForDynamoDb.identifiers
|
|
1150
|
+
)
|
|
1151
|
+
_izContext.logger.debug("identifiersForCreateData", identifiersForCreateData);
|
|
1152
|
+
|
|
1153
|
+
await dynamodbSharedLib.putItem(
|
|
1154
|
+
_izContext,
|
|
1155
|
+
await dynamodbSharedLib.tableName(
|
|
1156
|
+
_izContext,
|
|
1157
|
+
createDataDetail.tableName,
|
|
1158
|
+
createDataDetail.serviceTag
|
|
1159
|
+
),
|
|
1160
|
+
{
|
|
1161
|
+
...identifiersForCreateData,
|
|
1162
|
+
...objInstanceFullForDynamoDb.fields
|
|
1163
|
+
}
|
|
1164
|
+
);
|
|
1165
|
+
|
|
1166
|
+
objInstanceFullForDynamoDb.fields = {} // prevent using fieldNames from other tableName
|
|
1167
|
+
if (allAwaitingStepsId.length == 0) {
|
|
1168
|
+
let messageObject = {
|
|
1169
|
+
objType: objType,
|
|
1170
|
+
objInstanceFull: {
|
|
1171
|
+
identifiers: objInstanceFullForDynamoDb.identifiers,
|
|
1172
|
+
fields: objInstanceFullForDynamoDb.fields
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
if (callingFlowConfig[callingFlowSharedLib.consts.CALLINGFLOW_PROPERTYNAME]) {
|
|
1177
|
+
// send message to SNS OutCreateNodeComplete
|
|
1178
|
+
_izContext.logger.debug("HAVE CallingFlow");
|
|
1179
|
+
messageObject = callingFlowSharedLib.addPassBackPropertiesToSnsResponseMessageObject(callingFlowConfig, messageObject);
|
|
1180
|
+
|
|
1181
|
+
let messageAttributes = callingFlowSharedLib.addCallingFlowToSnsResponseMessageAttributes(callingFlowConfig, {});
|
|
1182
|
+
let outCreateNodeCompleteTopic = await snsSharedLib.snsTopicArnByFlowSchema(_izContext, TOPIC_NAME_GENERATE_CODE.outCreateNodeComplete)
|
|
1183
|
+
let messageParams = {
|
|
1184
|
+
Message: JSON.stringify(messageObject),
|
|
1185
|
+
MessageAttributes: sns.createStringMessageAttributes(_izContext, messageAttributes),
|
|
1186
|
+
TopicArn: outCreateNodeCompleteTopic,
|
|
1187
|
+
};
|
|
1188
|
+
|
|
1189
|
+
_izContext.logger.debug("messageParams OutCreateNode ::::::: ", messageParams);
|
|
1190
|
+
await sns.publishAsync(_izContext, messageParams);
|
|
1191
|
+
}
|
|
1192
|
+
return {
|
|
1193
|
+
objType: objType,
|
|
1194
|
+
objInstanceFull: objInstanceFullForDynamoDb,
|
|
1195
|
+
relationships: requestParams.relationships || [],
|
|
1196
|
+
status: "complete",
|
|
1197
|
+
errorsFound: []
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
} else if (createDataDetail.storageType == consts.STORAGE_TYPES.graph) {
|
|
1202
|
+
_izContext.logger.debug("::::::Graph::::::", { storageTag, objInstanceFull });
|
|
1203
|
+
|
|
1204
|
+
Object.assign(objInstanceFullForGraph.fields, createObjInstanceFullFieldsByStorageTag(_izContext, storageTag, createDataDetail))
|
|
1205
|
+
_izContext.logger.debug("objInstanceFull before send to Graph", objInstanceFullForGraph)
|
|
1206
|
+
|
|
1207
|
+
// allStorageTagComplete = false;
|
|
1208
|
+
allAwaitingStepsId.push(await asyncFlowSharedLib.createAwaitingStepId(
|
|
1209
|
+
(hash({
|
|
1210
|
+
objType: objType,
|
|
1211
|
+
graphServerTag: storageTag,
|
|
1212
|
+
identifiers: objInstanceFullForGraph.identifiers,
|
|
1213
|
+
callingFlowProperties: callingFlowConfig.callingFlowProperties || {}
|
|
1214
|
+
})),
|
|
1215
|
+
PREFIX.CREATE_OBJECT_ASYNC
|
|
1216
|
+
));
|
|
1217
|
+
listOfObjectForCreates.push({
|
|
1218
|
+
[storageTag]: {
|
|
1219
|
+
objInstanceFull: {
|
|
1220
|
+
identifiers: objInstanceFullForGraph.identifiers,
|
|
1221
|
+
fields: objInstanceFullForGraph.fields
|
|
1222
|
+
},
|
|
1223
|
+
allStorageTagComplete: false
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
|
|
1227
|
+
_izContext.logger.debug("FIRST", listOfObjectForCreates)
|
|
1228
|
+
|
|
1229
|
+
} else if (createDataDetail.storageType === consts.STORAGE_TYPES.externalTopic) {
|
|
1230
|
+
_izContext.logger.debug("::::::externalTopic::::::", { storageTag, createDataDetail });
|
|
1231
|
+
Object.assign(objInstanceFullForExternalTopic.fields, createObjInstanceFullFieldsByStorageTag(_izContext, storageTag, createDataDetail))
|
|
1232
|
+
_izContext.logger.debug("objInstanceFull before send to external topic", objInstanceFullForExternalTopic)
|
|
1233
|
+
|
|
1234
|
+
allAwaitingStepsId.push(await asyncFlowSharedLib.createAwaitingStepId(
|
|
1235
|
+
(hash({
|
|
1236
|
+
objType: objType,
|
|
1237
|
+
graphServerTag: storageTag,
|
|
1238
|
+
identifiers: objInstanceFullForGraph.identifiers,
|
|
1239
|
+
callingFlowProperties: callingFlowConfig.callingFlowProperties || {}
|
|
1240
|
+
})),
|
|
1241
|
+
PREFIX.CREATE_OBJECT_EXTERNAL_TOPIC
|
|
1242
|
+
));
|
|
1243
|
+
|
|
1244
|
+
let sendToCreateExternalTopic = {
|
|
1245
|
+
Message: JSON.stringify({ objType, objInstanceFull: objInstanceFullForExternalTopic, relationships: requestParams.relationships }),
|
|
1246
|
+
TopicArn: `arn:aws:sns:${createDataDetail.region}:${createDataDetail.accountId}:${createDataDetail.serviceTag}_${createDataDetail.stage}_Create_In`
|
|
1247
|
+
};
|
|
1248
|
+
_izContext.logger.debug("Request params before send to create endpoint:", sendToCreateExternalTopic);
|
|
1249
|
+
|
|
1250
|
+
await sns.publishAsync(_izContext, sendToCreateExternalTopic)
|
|
1251
|
+
return sendToCreateExternalTopic
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
_izContext.logger.debug("[1]listOfObjectForCreates:::", listOfObjectForCreates);
|
|
1255
|
+
|
|
1256
|
+
/// step save awaitingMultipleStep of storageType graph ...........................................................
|
|
1257
|
+
if (!settings.userAgent) {
|
|
1258
|
+
_izContext.logger.debug("not api will create awaitingStep")
|
|
1259
|
+
await asyncFlowSharedLib.createAwaitingMultipleSteps(
|
|
1260
|
+
_izContext,
|
|
1261
|
+
allAwaitingStepsId,
|
|
1262
|
+
asyncFlowSharedLib.createPendingStepId((hash({ objType: objType, identifiers: objInstanceFull.identifiers })), PREFIX.CREATE_OBJECT_ASYNC_COMPLETE)
|
|
1263
|
+
);
|
|
1264
|
+
}
|
|
1265
|
+
//............................................................................................................
|
|
1266
|
+
|
|
1267
|
+
// process storageType : graph
|
|
1268
|
+
let messageObject = {};
|
|
1269
|
+
for (let objectCreate of listOfObjectForCreates) {
|
|
1270
|
+
|
|
1271
|
+
for (let [graphServiceName, objectForCreate] of Object.entries(objectCreate)) {
|
|
1272
|
+
_izContext.logger.debug("Loop each graph:", {
|
|
1273
|
+
[graphServiceName]: objectForCreate
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1276
|
+
if (objectForCreate.allStorageTagComplete == false) { // needless check because in listOfObjectForCreates push case graph only!
|
|
1277
|
+
messageObject = {
|
|
1278
|
+
objType: objType,
|
|
1279
|
+
objInstanceFull: objectForCreate.objInstanceFull,
|
|
1280
|
+
relationships: requestParams.relationships || []
|
|
1281
|
+
};
|
|
1282
|
+
};
|
|
1283
|
+
|
|
1284
|
+
_izContext.logger.debug("SENT MESSAGE EACH GRAPH::::", { graphServiceName, messageObject, callingFlowConfig })
|
|
1285
|
+
|
|
1286
|
+
Object.assign(messageObject, {
|
|
1287
|
+
settings: { updatePropertiesOnMatch: false },
|
|
1288
|
+
originTimestamp: Date.now(),
|
|
1289
|
+
});
|
|
1290
|
+
if (settings.userAgent) {
|
|
1291
|
+
_izContext.logger.debug("have userAgent will invoke GraphHandler")
|
|
1292
|
+
let createNodeResult = await graphSharedLibs.createNodeV2(
|
|
1293
|
+
_izContext,
|
|
1294
|
+
graphServiceName,
|
|
1295
|
+
objType,
|
|
1296
|
+
objInstanceFullForGraph,
|
|
1297
|
+
requestParams.relationships || [],
|
|
1298
|
+
Date.now(),
|
|
1299
|
+
{
|
|
1300
|
+
updatePropertiesOnMatch: false
|
|
1301
|
+
}
|
|
1302
|
+
)
|
|
1303
|
+
return createNodeResult
|
|
1304
|
+
|
|
1305
|
+
} else if (settings.directInvoke) {
|
|
1306
|
+
_izContext.logger.debug("Direction Invoke case will invoke GraphHandlerInv")
|
|
1307
|
+
let createNodeResult = await graphSharedLibs.createNodeV2(
|
|
1308
|
+
_izContext,
|
|
1309
|
+
graphServiceName,
|
|
1310
|
+
objType,
|
|
1311
|
+
objInstanceFullForGraph,
|
|
1312
|
+
requestParams.relationships,
|
|
1313
|
+
Date.now(),
|
|
1314
|
+
{
|
|
1315
|
+
updatePropertiesOnMatch: false
|
|
1316
|
+
}
|
|
1317
|
+
);
|
|
1318
|
+
|
|
1319
|
+
return createNodeResult;
|
|
1320
|
+
} else {
|
|
1321
|
+
_izContext.logger.debug("not have userAgent will send Message to GraphHandler")
|
|
1322
|
+
messageObject = callingFlowSharedLib.addCallingFlowToSnsRequestMessageObject(
|
|
1323
|
+
messageObject,
|
|
1324
|
+
callingFlowSharedLib.addParentCallingFlowConfig(
|
|
1325
|
+
callingFlowConfig, // receive parent callingFlowConfig.
|
|
1326
|
+
callingFlowSharedLib.createCallingFlowConfig( // calling flow own service
|
|
1327
|
+
await lambdaSharedLib.lambdaFunctionName(_izContext, TOPIC_NAME_GENERATE_CODE.createNodeComplete), {}
|
|
1328
|
+
)
|
|
1329
|
+
)
|
|
1330
|
+
);
|
|
1331
|
+
|
|
1332
|
+
let messageToCreateObject = {
|
|
1333
|
+
Message: JSON.stringify(messageObject),
|
|
1334
|
+
TopicArn: await snsSharedLib.snsTopicArnByFlowSchema(_izContext, TOPIC_NAME_GRAPH_HANDLER.inCreateNode, graphServiceName)
|
|
1335
|
+
};
|
|
1336
|
+
_izContext.logger.debug("RequestParams before send to sqs messageToCreateObject ::::::: ", messageToCreateObject);
|
|
1337
|
+
await sns.publishAsync(_izContext, messageToCreateObject);
|
|
1338
|
+
|
|
1339
|
+
return messageObject
|
|
1340
|
+
}
|
|
1341
|
+
};
|
|
1342
|
+
};
|
|
1343
|
+
|
|
1344
|
+
function createObjInstanceFullFieldsByStorageTag(_izContext, storageTag, createDataDetail) {
|
|
1345
|
+
let fields = {};
|
|
1346
|
+
for (let fieldName of Object.keys(requestParams.fieldNames)) {
|
|
1347
|
+
if ((createDataDetails[storageTag].fieldNames.includes(fieldName)) &&
|
|
1348
|
+
(createDataDetail.fieldNames.includes(fieldName))) {
|
|
1349
|
+
if (!objInstanceFull.identifiers.hasOwnProperty(fieldName)) {
|
|
1350
|
+
if (!fields.hasOwnProperty(fieldName)) {
|
|
1351
|
+
Object.assign(fields, {
|
|
1352
|
+
[fieldName]: requestParams.fieldNames[fieldName]
|
|
1353
|
+
})
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
return fields
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
async function sharedCreateCompleteEndpoint(_izContext, returnValue, status, errorsFound, graphServiceTag, passBackProperties) {
|
|
1363
|
+
let existsNode = null;
|
|
1364
|
+
|
|
1365
|
+
if (Object.keys(returnValue.queryResult.returnCreateNode.existsNode).length) {
|
|
1366
|
+
existsNode = {
|
|
1367
|
+
objType: {
|
|
1368
|
+
objectType: returnValue.requestParams.objType.objectType,
|
|
1369
|
+
serviceTag: returnValue.requestParams.objType.serviceTag
|
|
1370
|
+
},
|
|
1371
|
+
objInstanceFull: returnValue.queryResult.returnCreateNode.existsNode.objInstanceFull
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
let awaitingStepId = await asyncFlowSharedLib.createAwaitingStepId(
|
|
1376
|
+
(hash({
|
|
1377
|
+
objType: returnValue.requestParams.objType,
|
|
1378
|
+
graphServerTag: graphServiceTag,
|
|
1379
|
+
identifiers: returnValue.requestParams.objInstanceFull.identifiers,
|
|
1380
|
+
callingFlowProperties: passBackProperties.passBackProperties.parentPassBackProperties.callingFlowProperties || {}
|
|
1381
|
+
})),
|
|
1382
|
+
PREFIX.CREATE_OBJECT_ASYNC
|
|
1383
|
+
)
|
|
1384
|
+
_izContext.logger.debug("awaitingStepId:", awaitingStepId);
|
|
1385
|
+
|
|
1386
|
+
let recordAwaitingSteps = await dynamodbSharedLib.query(
|
|
1387
|
+
_izContext,
|
|
1388
|
+
await dynamodbSharedLib.tableName(_izContext, "AwaitingMultipleSteps"),
|
|
1389
|
+
{
|
|
1390
|
+
awaitingStepId: awaitingStepId
|
|
1391
|
+
}
|
|
1392
|
+
);
|
|
1393
|
+
_izContext.logger.debug("record awaitingSteps::", recordAwaitingSteps);
|
|
1394
|
+
|
|
1395
|
+
await Promise.all(
|
|
1396
|
+
recordAwaitingSteps.Items.map(async ({ pendingStepId }) => {
|
|
1397
|
+
if (await asyncFlowSharedLib.checkAllAwaitingStepsFinished(
|
|
1398
|
+
_izContext,
|
|
1399
|
+
pendingStepId,
|
|
1400
|
+
awaitingStepId,
|
|
1401
|
+
errorsFound
|
|
1402
|
+
)) {
|
|
1403
|
+
_izContext.logger.debug("finish all awaitingStep");
|
|
1404
|
+
|
|
1405
|
+
let messageObject = {
|
|
1406
|
+
objType: {
|
|
1407
|
+
objectType: returnValue.requestParams.objType.objectType,
|
|
1408
|
+
serviceTag: returnValue.requestParams.objType.serviceTag
|
|
1409
|
+
},
|
|
1410
|
+
objInstanceFull: returnValue.queryResult.returnCreateNode.objInstanceFull,
|
|
1411
|
+
relationships: returnValue.queryResult.returnCreateNode.relationships,
|
|
1412
|
+
existsNode: existsNode,
|
|
1413
|
+
status: status,
|
|
1414
|
+
errorsFound: errorsFound
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
messageObject = callingFlowSharedLib.addParentPassBackPropertiesToSnsResponseMessageObject(passBackProperties, messageObject)
|
|
1418
|
+
let messageAttributes = callingFlowSharedLib.addParentPassBackCallingFlowToSnsResponseMessageAttributes(passBackProperties, {})
|
|
1419
|
+
|
|
1420
|
+
let sendMessageOutCreateObjectComplete = {
|
|
1421
|
+
Message: JSON.stringify(messageObject),
|
|
1422
|
+
MessageAttributes: sns.createStringMessageAttributes(_izContext, messageAttributes),
|
|
1423
|
+
TopicArn: await snsSharedLib.snsTopicArnByFlowSchema(_izContext, TOPIC_NAME_GENERATE_CODE.outCreateNodeComplete)
|
|
1424
|
+
};
|
|
1425
|
+
_izContext.logger.debug("Send message to OutCreateObjectComplete :::>", sendMessageOutCreateObjectComplete)
|
|
1426
|
+
await sns.publishAsync(_izContext, sendMessageOutCreateObjectComplete);
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
await asyncFlowSharedLib.removeAwaitingMultipleStep(
|
|
1430
|
+
_izContext,
|
|
1431
|
+
awaitingStepId,
|
|
1432
|
+
pendingStepId,
|
|
1433
|
+
errorsFound
|
|
1434
|
+
);
|
|
1435
|
+
|
|
1436
|
+
})
|
|
1437
|
+
)
|
|
1438
|
+
|
|
1439
|
+
return {
|
|
1440
|
+
returnValue: returnValue,
|
|
1441
|
+
status: status,
|
|
1442
|
+
errorsFound: errorsFound
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1093
1446
|
module.exports = {
|
|
1094
1447
|
sendMsgOutComplete,
|
|
1095
1448
|
messageToDlq,
|
|
@@ -1110,7 +1463,9 @@ module.exports = {
|
|
|
1110
1463
|
|
|
1111
1464
|
createFieldForUpdateDynamoDb,
|
|
1112
1465
|
createBasicRelationshipsProperties,
|
|
1113
|
-
createFieldNamesFromRequestParamsByObjectSchema
|
|
1466
|
+
createFieldNamesFromRequestParamsByObjectSchema,
|
|
1467
|
+
sharedCreateEndpoint,
|
|
1468
|
+
sharedCreateCompleteEndpoint
|
|
1114
1469
|
}
|
|
1115
1470
|
|
|
1116
1471
|
|
|
@@ -106,16 +106,18 @@ module.exports.getMain = async (
|
|
|
106
106
|
let throwWhenNotFoundSomeRecord = true;
|
|
107
107
|
let returnVersionedData = true;
|
|
108
108
|
|
|
109
|
-
if (requestParams.
|
|
110
|
-
if (requestParams.additionalParams.
|
|
111
|
-
returnSystemFieldsName
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
throwWhenNotFoundSomeRecord
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
returnVersionedData
|
|
118
|
-
|
|
109
|
+
if (requestParams.hasOwnProperty("additionalParams")) {
|
|
110
|
+
if (requestParams.additionalParams.hasOwnProperty("settings")) {
|
|
111
|
+
if (requestParams.additionalParams.settings.hasOwnProperty("returnSystemFieldsName") && requestParams.additionalParams.settings.returnSystemFieldsName === true) {
|
|
112
|
+
returnSystemFieldsName = true;
|
|
113
|
+
};
|
|
114
|
+
if (requestParams.additionalParams.settings.hasOwnProperty("throwWhenNotFoundSomeRecord") && requestParams.additionalParams.settings.throwWhenNotFoundSomeRecord === false) {
|
|
115
|
+
throwWhenNotFoundSomeRecord = false;
|
|
116
|
+
};
|
|
117
|
+
if (requestParams.additionalParams.settings.hasOwnProperty("returnVersionedData") && requestParams.additionalParams.settings.returnVersionedData === false) {
|
|
118
|
+
returnVersionedData = false;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
119
121
|
};
|
|
120
122
|
|
|
121
123
|
//(<beforeQuery>)
|
|
@@ -91,15 +91,18 @@ module.exports.updateMain = async (
|
|
|
91
91
|
let returnSystemFieldsName = false;
|
|
92
92
|
let returnOldData = false;
|
|
93
93
|
|
|
94
|
-
if (requestParams.
|
|
95
|
-
if (requestParams.additionalParams.
|
|
96
|
-
returnSystemFieldsName
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
returnOldData
|
|
100
|
-
|
|
94
|
+
if (requestParams.hasOwnProperty("additionalParams")) {
|
|
95
|
+
if (requestParams.additionalParams.hasOwnProperty("settings")) {
|
|
96
|
+
if (requestParams.additionalParams.settings.hasOwnProperty("returnSystemFieldsName") && requestParams.additionalParams.settings.returnSystemFieldsName === true) {
|
|
97
|
+
returnSystemFieldsName = true;
|
|
98
|
+
}
|
|
99
|
+
if (requestParams.additionalParams.settings.hasOwnProperty("returnOldData") && requestParams.additionalParams.settings.returnOldData === true) {
|
|
100
|
+
returnOldData = true;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
101
103
|
};
|
|
102
104
|
|
|
105
|
+
|
|
103
106
|
let errorsFound = [];
|
|
104
107
|
|
|
105
108
|
const objType = createObjType(requestParams.objectType);
|