@itentialopensource/adapter-utils 5.10.16 → 5.10.18
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/README.md +1 -1
- package/lib/connectorRest.js +25 -163
- package/lib/constants.js +14 -0
- package/lib/propertyUtil.js +9 -1
- package/lib/restHandler.js +39 -120
- package/lib/throttle.js +11 -1
- package/lib/translatorUtil.js +177 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@ Itential Adapter Utilities
|
|
|
3
3
|
|
|
4
4
|
Itential Adapter Utilities is a set of Node.js runtime libraries used by Itential Adapters.
|
|
5
5
|
|
|
6
|
-
Many of the capabilities supported in Itential Adapters are built into this library so that they can
|
|
6
|
+
Many of the capabilities supported in Itential Adapters are built into this library so that they can be better maintained and added to adapters.
|
|
7
7
|
|
|
8
8
|
# Usage
|
|
9
9
|
|
package/lib/connectorRest.js
CHANGED
|
@@ -267,54 +267,6 @@ function waitForSystem(callProperties) {
|
|
|
267
267
|
});
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
-
/*
|
|
271
|
-
* INTERNAL FUNCTION: Get the best match for the moc k data response
|
|
272
|
-
*/
|
|
273
|
-
function matchMock(uriPath, method, type, mockresponses, respDatatype) {
|
|
274
|
-
// Go through the mock data keys to find the proper data to return
|
|
275
|
-
for (let p = 0; p < mockresponses.length; p += 1) {
|
|
276
|
-
// is this the mock data for this call
|
|
277
|
-
if (Object.hasOwnProperty.call(mockresponses[p], 'name')
|
|
278
|
-
&& uriPath === mockresponses[p].name) {
|
|
279
|
-
if (Object.hasOwnProperty.call(mockresponses[p], 'method')
|
|
280
|
-
&& method.toUpperCase() === mockresponses[p].method.toUpperCase()) {
|
|
281
|
-
if (Object.hasOwnProperty.call(mockresponses[p], 'type')
|
|
282
|
-
&& type.toUpperCase() === mockresponses[p].type.toUpperCase()) {
|
|
283
|
-
// This is the mock data we really want as it best matches the request
|
|
284
|
-
const specificResp = {
|
|
285
|
-
status: 'success',
|
|
286
|
-
code: 200,
|
|
287
|
-
response: {}
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
if (Object.hasOwnProperty.call(mockresponses[p], 'response')) {
|
|
291
|
-
// if a status is defined in the response, use it
|
|
292
|
-
if (Object.hasOwnProperty.call(mockresponses[p].response, 'response')
|
|
293
|
-
&& Object.hasOwnProperty.call(mockresponses[p].response, 'status')) {
|
|
294
|
-
specificResp.code = mockresponses[p].response.status;
|
|
295
|
-
|
|
296
|
-
if (respDatatype && respDatatype.toUpperCase() === 'XML2JSON') {
|
|
297
|
-
specificResp.response = mockresponses[p].response.response;
|
|
298
|
-
} else {
|
|
299
|
-
specificResp.response = JSON.stringify(mockresponses[p].response.response);
|
|
300
|
-
}
|
|
301
|
-
} else if (respDatatype && respDatatype.toUpperCase() === 'XML2JSON') {
|
|
302
|
-
// if no response field, assume that the entire data is the response
|
|
303
|
-
specificResp.response = mockresponses[p].response;
|
|
304
|
-
} else {
|
|
305
|
-
specificResp.response = JSON.stringify(mockresponses[p].response);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
return specificResp;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return null;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
270
|
/*
|
|
319
271
|
* INTERNAL FUNCTION: recursively inspect body data if heirarchical
|
|
320
272
|
*/
|
|
@@ -347,20 +299,20 @@ function checkBodyData(uriPath, method, reqBdObj, mockresponses, respDatatype) {
|
|
|
347
299
|
for (let a = 0; a < bVal.length; a += 1) {
|
|
348
300
|
// should match fieldName-fieldValue
|
|
349
301
|
const compStr = `${reqBKeys[k]}-${bVal[a]}`;
|
|
350
|
-
specificResp =
|
|
302
|
+
specificResp = transUtilInst.matchResponse(uriPath, method, compStr, mockresponses, respDatatype);
|
|
351
303
|
|
|
352
304
|
// if the data match is found break the for loop - will return below
|
|
353
|
-
if (specificResp !== null) {
|
|
305
|
+
if (specificResp !== null && specificResp.response) {
|
|
354
306
|
break;
|
|
355
307
|
}
|
|
356
308
|
}
|
|
357
309
|
} else {
|
|
358
310
|
// should match fieldName-fieldValue
|
|
359
311
|
const compStr = `${reqBKeys[k]}-${bVal}`;
|
|
360
|
-
specificResp =
|
|
312
|
+
specificResp = transUtilInst.matchResponse(uriPath, method, compStr, mockresponses, respDatatype);
|
|
361
313
|
}
|
|
362
314
|
|
|
363
|
-
if (specificResp !== null) {
|
|
315
|
+
if (specificResp !== null && specificResp.response) {
|
|
364
316
|
break;
|
|
365
317
|
}
|
|
366
318
|
}
|
|
@@ -441,56 +393,9 @@ function returnStub(request, entitySchema, callProperties) {
|
|
|
441
393
|
}
|
|
442
394
|
|
|
443
395
|
// if there are path variables, see if there is something that matches a specific variable
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
uriTemp[0] = uriTemp[0].replace(/{pathv/g, '/{pathv');
|
|
448
|
-
uriTemp[0] = uriTemp[0].replace(/{version/g, '/{version');
|
|
449
|
-
uriTemp[0] = uriTemp[0].replace(/{base/g, '/{base');
|
|
450
|
-
uriTemp[0] = uriTemp[0].replace(/\/\//g, '/');
|
|
451
|
-
|
|
452
|
-
// remove basepath from both paths
|
|
453
|
-
// get rid of base path from the uriPath
|
|
454
|
-
uriTemp[0] = uriTemp[0].replace(/\/{base_path}/g, '');
|
|
455
|
-
// if a base path was added to the request, remove it
|
|
456
|
-
if (callProperties && callProperties.base_path && callProperties.base_path !== '/') {
|
|
457
|
-
actTemp[0] = actTemp[0].replace(callProperties.base_path, '');
|
|
458
|
-
} else if (basepath && basepath !== '/') {
|
|
459
|
-
actTemp[0] = actTemp[0].replace(basepath, '');
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// remove version from both paths
|
|
463
|
-
// get rid of version from the uriPath
|
|
464
|
-
uriTemp[0] = uriTemp[0].replace(/\/{version}/g, '');
|
|
465
|
-
// if a version was added to the request, remove it
|
|
466
|
-
if (callProperties && callProperties.version) {
|
|
467
|
-
actTemp[0] = actTemp[0].replace(`/${callProperties.version}`, '');
|
|
468
|
-
} else if (version && version !== '/') {
|
|
469
|
-
actTemp[0] = actTemp[0].replace(`/${version}`, '');
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
const uriArray = uriTemp[0].split('/');
|
|
473
|
-
const actArray = actTemp[0].split('/');
|
|
474
|
-
|
|
475
|
-
// if this is one of the generic requests need to pad the actual array or mock data for specific path variable will not work
|
|
476
|
-
if (entitySchema.entitypath.indexOf('/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}/{pathv11}/{pathv12}/{pathv13}/{pathv14}/{pathv15}/{pathv16}/{pathv17}/{pathv18}/{pathv19}/{pathv20}?{query}') >= 0) {
|
|
477
|
-
for (let e = actArray.length; e < uriArray.length; e += 1) {
|
|
478
|
-
actArray.push('');
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
// the number of items in both should be the same
|
|
483
|
-
if (uriArray.length === actArray.length) {
|
|
484
|
-
for (let i = 0; i < uriArray.length; i += 1) {
|
|
485
|
-
if (uriArray[i].indexOf('{pathv') >= 0) {
|
|
486
|
-
specificResp = matchMock(uriPath, method, actArray[i], mockresponses, entitySchema.responseDatatype);
|
|
487
|
-
|
|
488
|
-
if (specificResp !== null) {
|
|
489
|
-
return specificResp;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
}
|
|
396
|
+
specificResp = transUtilInst.getRespObjKeyFromPath(uriPath, reqPath, callProperties, basepath, version, method, false, entitySchema);
|
|
397
|
+
if (specificResp !== null && specificResp.response) {
|
|
398
|
+
return specificResp;
|
|
494
399
|
}
|
|
495
400
|
|
|
496
401
|
// if there are queiries or options, see if there is something that matches a specific input
|
|
@@ -504,9 +409,9 @@ function returnStub(request, entitySchema, callProperties) {
|
|
|
504
409
|
if (qval !== undefined && qval !== null && qval !== '') {
|
|
505
410
|
// stringifies it - in case it was not a string
|
|
506
411
|
qval = `${qval}`;
|
|
507
|
-
specificResp =
|
|
412
|
+
specificResp = transUtilInst.matchResponse(uriPath, method, qval, mockresponses, entitySchema.responseDatatype);
|
|
508
413
|
|
|
509
|
-
if (specificResp !== null) {
|
|
414
|
+
if (specificResp !== null && specificResp.response) {
|
|
510
415
|
return specificResp;
|
|
511
416
|
}
|
|
512
417
|
}
|
|
@@ -515,79 +420,36 @@ function returnStub(request, entitySchema, callProperties) {
|
|
|
515
420
|
|
|
516
421
|
// if there is a request body, see if there is a specific response for body
|
|
517
422
|
if (reqBody) {
|
|
518
|
-
specificResp =
|
|
519
|
-
|
|
520
|
-
if (specificResp !== null) {
|
|
423
|
+
specificResp = transUtilInst.matchResponse(uriPath, method, 'WITHBODY', mockresponses, entitySchema.responseDatatype);
|
|
424
|
+
if (specificResp !== null && specificResp.response) {
|
|
521
425
|
return specificResp;
|
|
522
426
|
}
|
|
523
427
|
}
|
|
524
428
|
|
|
525
|
-
// if there are path variables, see if there is
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
uriTemp[0] = uriTemp[0].replace(/{pathv/g, '/{pathv');
|
|
530
|
-
uriTemp[0] = uriTemp[0].replace(/{version/g, '/{version');
|
|
531
|
-
uriTemp[0] = uriTemp[0].replace(/{base_path}/g, '/{base_path}');
|
|
532
|
-
uriTemp[0] = uriTemp[0].replace(/\/\//g, '/');
|
|
533
|
-
|
|
534
|
-
// remove basepath from both paths
|
|
535
|
-
// get rid of base path from the uriPath
|
|
536
|
-
uriTemp[0] = uriTemp[0].replace(/\/{base_path}/g, '');
|
|
537
|
-
// if a base path was added to the request, remove it
|
|
538
|
-
if (callProperties && callProperties.base_path && callProperties.base_path !== '/') {
|
|
539
|
-
actTemp[0] = actTemp[0].replace(callProperties.base_path, '');
|
|
540
|
-
} else if (basepath && basepath !== '/') {
|
|
541
|
-
actTemp[0] = actTemp[0].replace(basepath, '');
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
// remove version from both paths
|
|
545
|
-
// get rid of version from the uriPath
|
|
546
|
-
uriTemp[0] = uriTemp[0].replace(/\/{version}/g, '');
|
|
547
|
-
// if a version was added to the request, remove it
|
|
548
|
-
if (callProperties && callProperties.version) {
|
|
549
|
-
actTemp[0] = actTemp[0].replace(`/${callProperties.version}`, '');
|
|
550
|
-
} else if (version && version !== '/') {
|
|
551
|
-
actTemp[0] = actTemp[0].replace(`/${version}`, '');
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
const uriArray = uriTemp[0].split('/');
|
|
555
|
-
const actArray = actTemp[0].split('/');
|
|
556
|
-
|
|
557
|
-
// the number of items in both should be the same
|
|
558
|
-
if (uriArray.length === actArray.length) {
|
|
559
|
-
let cnt = 1;
|
|
560
|
-
for (let i = 0; i < uriArray.length; i += 1) {
|
|
561
|
-
if (uriArray[i].indexOf('{pathv') >= 0) {
|
|
562
|
-
specificResp = matchMock(uriPath, method, `WITHPATHV${cnt}`, mockresponses, entitySchema.responseDatatype);
|
|
563
|
-
|
|
564
|
-
if (specificResp !== null) {
|
|
565
|
-
return specificResp;
|
|
566
|
-
}
|
|
567
|
-
cnt += 1;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
}
|
|
429
|
+
// if there are path variables, see if there is something that matches a specific variable
|
|
430
|
+
specificResp = transUtilInst.getRespObjKeyFromPath(uriPath, reqPath, callProperties, basepath, version, method, true, entitySchema);
|
|
431
|
+
if (specificResp !== null && specificResp.response) {
|
|
432
|
+
return specificResp;
|
|
571
433
|
}
|
|
572
434
|
|
|
573
435
|
// if there are queiries or options, see if there is a specific response for query or options
|
|
574
436
|
if (uriPath.indexOf('?') >= 0) {
|
|
575
|
-
specificResp =
|
|
437
|
+
specificResp = transUtilInst.matchResponse(uriPath, method, 'WITHQUERY', mockresponses, entitySchema.responseDatatype);
|
|
576
438
|
|
|
577
|
-
if (specificResp !== null) {
|
|
439
|
+
if (specificResp !== null && specificResp.response) {
|
|
578
440
|
return specificResp;
|
|
579
441
|
}
|
|
580
442
|
|
|
581
|
-
specificResp =
|
|
443
|
+
specificResp = transUtilInst.matchResponse(uriPath, method, 'WITHOPTIONS', mockresponses, entitySchema.responseDatatype);
|
|
582
444
|
|
|
583
|
-
if (specificResp !== null) {
|
|
445
|
+
if (specificResp !== null && specificResp.response) {
|
|
584
446
|
return specificResp;
|
|
585
447
|
}
|
|
586
448
|
}
|
|
587
449
|
|
|
588
|
-
specificResp =
|
|
450
|
+
specificResp = transUtilInst.matchResponse(uriPath, method, 'DEFAULT', mockresponses, entitySchema.responseDatatype);
|
|
589
451
|
|
|
590
|
-
if (specificResp !== null) {
|
|
452
|
+
if (specificResp !== null && specificResp.response) {
|
|
591
453
|
return specificResp;
|
|
592
454
|
}
|
|
593
455
|
|
|
@@ -3244,7 +3106,7 @@ function requestAuthenticate(request, entitySchema, invalidToken, callProperties
|
|
|
3244
3106
|
}
|
|
3245
3107
|
|
|
3246
3108
|
// format the authentication string
|
|
3247
|
-
log.debug(`${origin}: ${JSON.stringify(propUtilInst.scrubSensitiveInfo(tres, addSensitiveItems))} being used
|
|
3109
|
+
log.debug(`${origin}: ${JSON.stringify(propUtilInst.scrubSensitiveInfo(tres, addSensitiveItems))} being used`);
|
|
3248
3110
|
const authStrs = [];
|
|
3249
3111
|
if (callProperties && callProperties.authentication && callProperties.authentication.auth_field_format) {
|
|
3250
3112
|
if (Array.isArray(callProperties.authentication.auth_field_format)) {
|
|
@@ -3306,7 +3168,7 @@ function requestAuthenticate(request, entitySchema, invalidToken, callProperties
|
|
|
3306
3168
|
return callback(null, errorObj);
|
|
3307
3169
|
}
|
|
3308
3170
|
|
|
3309
|
-
log.debug(`${origin}: ${JSON.stringify(propUtilInst.scrubSensitiveInfo(tokenObj, addSensitiveItems))} being used
|
|
3171
|
+
log.debug(`${origin}: ${JSON.stringify(propUtilInst.scrubSensitiveInfo(tokenObj, addSensitiveItems))} being used`);
|
|
3310
3172
|
const authStrs = [];
|
|
3311
3173
|
if (callProperties && callProperties.authentication && callProperties.authentication.auth_field_format) {
|
|
3312
3174
|
if (Array.isArray(callProperties.authentication.auth_field_format)) {
|
|
@@ -4579,7 +4441,7 @@ class ConnectorRest {
|
|
|
4579
4441
|
return waitForMongo()
|
|
4580
4442
|
.then(() => {
|
|
4581
4443
|
if (archiving) {
|
|
4582
|
-
const colRes = this.dbUtil.createCollection(archiveColl, (err, res) => {
|
|
4444
|
+
const colRes = this.dbUtil.createCollection(archiveColl, null, null, (err, res) => {
|
|
4583
4445
|
if (err) {
|
|
4584
4446
|
log.error(`${origin}: collection ${archiveColl} could not be created.`);
|
|
4585
4447
|
return callback(false);
|
|
@@ -5113,7 +4975,7 @@ class ConnectorRest {
|
|
|
5113
4975
|
try {
|
|
5114
4976
|
if (!throttleEnabled) {
|
|
5115
4977
|
log.error(`${origin}: Throttling not enabled, no queue`);
|
|
5116
|
-
return [];
|
|
4978
|
+
return callback([]);
|
|
5117
4979
|
}
|
|
5118
4980
|
|
|
5119
4981
|
return throttleEng.getQueue(callback);
|
package/lib/constants.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* @copyright Itential, LLC 2025 */
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
// Global Strings
|
|
5
|
+
globalStrings: {
|
|
6
|
+
pathVarMarker: '{pathv', // path variable format is {pathv#} - number is dynamic can not match
|
|
7
|
+
versionMarker: '{version}',
|
|
8
|
+
basePathMarker: '{base_path}',
|
|
9
|
+
withPathVarPrefix: 'WITHPATHV',
|
|
10
|
+
urlSplit: '?',
|
|
11
|
+
pathSplit: '/',
|
|
12
|
+
globalFlag: 'g'
|
|
13
|
+
}
|
|
14
|
+
};
|
package/lib/propertyUtil.js
CHANGED
|
@@ -550,6 +550,7 @@ class AdapterPropertyUtil {
|
|
|
550
550
|
name: entitySchema.responseObjects[i].name,
|
|
551
551
|
method: entitySchema.responseObjects[i].method,
|
|
552
552
|
type: entitySchema.responseObjects[i].type,
|
|
553
|
+
key: entitySchema.responseObjects[i].key || '',
|
|
553
554
|
file: entitySchema.responseObjects[i].mockFile
|
|
554
555
|
};
|
|
555
556
|
|
|
@@ -969,6 +970,7 @@ class AdapterPropertyUtil {
|
|
|
969
970
|
name: entitySchema.responseObjects[i].name,
|
|
970
971
|
method: entitySchema.responseObjects[i].method,
|
|
971
972
|
type: entitySchema.responseObjects[i].type,
|
|
973
|
+
key: entitySchema.responseObjects[i].key || '',
|
|
972
974
|
file: entitySchema.responseObjects[i].mockFile
|
|
973
975
|
};
|
|
974
976
|
|
|
@@ -1267,14 +1269,20 @@ class AdapterPropertyUtil {
|
|
|
1267
1269
|
retData[key] = this.scrubSensitiveInfo(retData[key], addItems);
|
|
1268
1270
|
}
|
|
1269
1271
|
} else {
|
|
1270
|
-
|
|
1272
|
+
let gotit = false;
|
|
1273
|
+
// go through sensitive word list to mask the entire string
|
|
1271
1274
|
for (let j = 0; j < sensList.length; j += 1) {
|
|
1272
1275
|
if (key.toLowerCase() === sensList[j]) {
|
|
1273
1276
|
// if sensitive, mask
|
|
1274
1277
|
retData[key] = '** masked **';
|
|
1278
|
+
gotit = true;
|
|
1275
1279
|
break;
|
|
1276
1280
|
}
|
|
1277
1281
|
}
|
|
1282
|
+
// if not masking the string as a whole - may need to parse part of it
|
|
1283
|
+
if (!gotit) {
|
|
1284
|
+
retData[key] = this.scrubSensitiveInfo(retData[key], addItems);
|
|
1285
|
+
}
|
|
1278
1286
|
}
|
|
1279
1287
|
});
|
|
1280
1288
|
|
package/lib/restHandler.js
CHANGED
|
@@ -28,31 +28,6 @@ let stripEscapes = false;
|
|
|
28
28
|
let returnResponseHeaders = true;
|
|
29
29
|
let healthcheckHeaders = null;
|
|
30
30
|
let xmlArrayKeys = null;
|
|
31
|
-
// INTERNAL FUNCTIONS
|
|
32
|
-
/*
|
|
33
|
-
* INTERNAL FUNCTION: Get the best match for the mock data response
|
|
34
|
-
*/
|
|
35
|
-
function matchResponse(uriPath, method, type, mockresponses) {
|
|
36
|
-
// Go through the mock data keys to find the proper data to return
|
|
37
|
-
for (let p = 0; p < mockresponses.length; p += 1) {
|
|
38
|
-
// is this the mock data for this call
|
|
39
|
-
if (Object.hasOwnProperty.call(mockresponses[p], 'name')
|
|
40
|
-
&& uriPath === mockresponses[p].name) {
|
|
41
|
-
if (Object.hasOwnProperty.call(mockresponses[p], 'method')
|
|
42
|
-
&& method.toUpperCase() === mockresponses[p].method.toUpperCase()) {
|
|
43
|
-
if (Object.hasOwnProperty.call(mockresponses[p], 'type')
|
|
44
|
-
&& type.toUpperCase() === mockresponses[p].type.toUpperCase()) {
|
|
45
|
-
// This is the Key we really want as it best matches the request
|
|
46
|
-
if (Object.hasOwnProperty.call(mockresponses[p], 'key')) {
|
|
47
|
-
return mockresponses[p].key;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
31
|
|
|
57
32
|
/*
|
|
58
33
|
* INTERNAL FUNCTION: recursively inspect body data if heirarchical
|
|
@@ -84,9 +59,12 @@ function checkBodyData(uriPath, method, reqBdObj, mockresponses) {
|
|
|
84
59
|
} else if (Array.isArray(bVal)) {
|
|
85
60
|
// if an array of data, need to check each data in the array
|
|
86
61
|
for (let a = 0; a < bVal.length; a += 1) {
|
|
87
|
-
// should match fieldName-fieldValue
|
|
62
|
+
// should match fieldName-fieldValue - NOTE: if we get the responseDatatype that should be passed in
|
|
88
63
|
const compStr = `${reqBKeys[k]}-${bVal[a]}`;
|
|
89
|
-
|
|
64
|
+
const response = transUtilInst.matchResponse(uriPath, method, compStr, mockresponses, null);
|
|
65
|
+
if (response) {
|
|
66
|
+
specificResp = response.key;
|
|
67
|
+
}
|
|
90
68
|
|
|
91
69
|
// if the data match is found break the for loop - will return below
|
|
92
70
|
if (specificResp !== null) {
|
|
@@ -94,9 +72,12 @@ function checkBodyData(uriPath, method, reqBdObj, mockresponses) {
|
|
|
94
72
|
}
|
|
95
73
|
}
|
|
96
74
|
} else {
|
|
97
|
-
// should match fieldName-fieldValue
|
|
75
|
+
// should match fieldName-fieldValue - NOTE: if we get the responseDatatype that should be passed in
|
|
98
76
|
const compStr = `${reqBKeys[k]}-${bVal}`;
|
|
99
|
-
|
|
77
|
+
const response = transUtilInst.matchResponse(uriPath, method, compStr, mockresponses, null);
|
|
78
|
+
if (response) {
|
|
79
|
+
specificResp = response.key;
|
|
80
|
+
}
|
|
100
81
|
}
|
|
101
82
|
|
|
102
83
|
if (specificResp !== null) {
|
|
@@ -271,48 +252,10 @@ function handleRestRequest(request, entityId, entitySchema, callProperties, filt
|
|
|
271
252
|
}
|
|
272
253
|
|
|
273
254
|
// if there are path variables, see if there is something that matches a specific variable
|
|
274
|
-
if (respObjKey === null
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
uriTemp[0] = uriTemp[0].replace(/{version/g, '/{version');
|
|
279
|
-
uriTemp[0] = uriTemp[0].replace(/{base/g, '/{base');
|
|
280
|
-
uriTemp[0] = uriTemp[0].replace(/\/\//g, '/');
|
|
281
|
-
|
|
282
|
-
// remove basepath from both paths
|
|
283
|
-
// get rid of base path from the uriPath
|
|
284
|
-
uriTemp[0] = uriTemp[0].replace(/\/{base_path}/g, '');
|
|
285
|
-
// if a base path was added to the request, remove it
|
|
286
|
-
if (callProperties && callProperties.base_path && callProperties.base_path !== '/') {
|
|
287
|
-
actTemp[0] = actTemp[0].replace(callProperties.base_path, '');
|
|
288
|
-
} else if (basepathGl && basepathGl !== '/') {
|
|
289
|
-
actTemp[0] = actTemp[0].replace(basepathGl, '');
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// remove version from both paths
|
|
293
|
-
// get rid of version from the uriPath
|
|
294
|
-
uriTemp[0] = uriTemp[0].replace(/\/{version}/g, '');
|
|
295
|
-
// if a version was added to the request, remove it
|
|
296
|
-
if (callProperties && callProperties.version) {
|
|
297
|
-
actTemp[0] = actTemp[0].replace(`/${callProperties.version}`, '');
|
|
298
|
-
} else if (versionGl && versionGl !== '/') {
|
|
299
|
-
actTemp[0] = actTemp[0].replace(`/${versionGl}`, '');
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
const uriArray = uriTemp[0].split('/');
|
|
303
|
-
const actArray = actTemp[0].split('/');
|
|
304
|
-
|
|
305
|
-
// the number of items in both should be the same
|
|
306
|
-
if (uriArray.length === actArray.length) {
|
|
307
|
-
for (let i = 0; i < uriArray.length; i += 1) {
|
|
308
|
-
if (uriArray[i].indexOf('{pathv') >= 0) {
|
|
309
|
-
respObjKey = matchResponse(uriPath, method, actArray[i], responseKeys);
|
|
310
|
-
|
|
311
|
-
if (respObjKey !== null) {
|
|
312
|
-
break;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
255
|
+
if (respObjKey === null) {
|
|
256
|
+
const specificResp = transUtilInst.getRespObjKeyFromPath(uriPath, reqPath, callProperties, basepathGl, versionGl, method, false, entitySchema);
|
|
257
|
+
if (specificResp) {
|
|
258
|
+
respObjKey = specificResp.key;
|
|
316
259
|
}
|
|
317
260
|
}
|
|
318
261
|
|
|
@@ -326,7 +269,10 @@ function handleRestRequest(request, entityId, entitySchema, callProperties, filt
|
|
|
326
269
|
if (qval !== undefined && qval !== null && qval !== '') {
|
|
327
270
|
// stringifies it - in case it was not a string
|
|
328
271
|
qval = `${qval}`;
|
|
329
|
-
|
|
272
|
+
const specificResp = transUtilInst.matchResponse(uriPath, method, qval, responseKeys, entitySchema.responseDatatype);
|
|
273
|
+
if (specificResp) {
|
|
274
|
+
respObjKey = specificResp.key;
|
|
275
|
+
}
|
|
330
276
|
|
|
331
277
|
if (respObjKey !== null) {
|
|
332
278
|
break;
|
|
@@ -337,68 +283,40 @@ function handleRestRequest(request, entityId, entitySchema, callProperties, filt
|
|
|
337
283
|
|
|
338
284
|
// if there is a request body, see if there is a specific response for body
|
|
339
285
|
if (respObjKey === null && reqBody) {
|
|
340
|
-
|
|
286
|
+
const specificResp = transUtilInst.matchResponse(uriPath, method, 'WITHBODY', responseKeys, entitySchema.responseDatatype);
|
|
287
|
+
if (specificResp) {
|
|
288
|
+
respObjKey = specificResp.key;
|
|
289
|
+
}
|
|
341
290
|
}
|
|
342
291
|
|
|
343
292
|
// if there are path variables, see if there is a specific response for path vars
|
|
344
|
-
if (respObjKey === null
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
uriTemp[0] = uriTemp[0].replace(/{version/g, '/{version');
|
|
349
|
-
uriTemp[0] = uriTemp[0].replace(/{base/g, '/{base');
|
|
350
|
-
uriTemp[0] = uriTemp[0].replace(/\/\//g, '/');
|
|
351
|
-
|
|
352
|
-
// remove basepath from both paths
|
|
353
|
-
// get rid of base path from the uriPath
|
|
354
|
-
uriTemp[0] = uriTemp[0].replace(/\/{base_path}/g, '');
|
|
355
|
-
// if a base path was added to the request, remove it
|
|
356
|
-
if (callProperties && callProperties.base_path && callProperties.base_path !== '/') {
|
|
357
|
-
actTemp[0] = actTemp[0].replace(callProperties.base_path, '');
|
|
358
|
-
} else if (basepathGl && basepathGl !== '/') {
|
|
359
|
-
actTemp[0] = actTemp[0].replace(basepathGl, '');
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
// remove version from both paths
|
|
363
|
-
// get rid of version from the uriPath
|
|
364
|
-
uriTemp[0] = uriTemp[0].replace(/\/{version}/g, '');
|
|
365
|
-
// if a version was added to the request, remove it
|
|
366
|
-
if (callProperties && callProperties.version) {
|
|
367
|
-
actTemp[0] = actTemp[0].replace(`/${callProperties.version}`, '');
|
|
368
|
-
} else if (versionGl && versionGl !== '/') {
|
|
369
|
-
actTemp[0] = actTemp[0].replace(`/${versionGl}`, '');
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
const uriArray = uriTemp[0].split('/');
|
|
373
|
-
const actArray = actTemp[0].split('/');
|
|
374
|
-
|
|
375
|
-
// the number of items in both should be the same
|
|
376
|
-
if (uriArray.length === actArray.length) {
|
|
377
|
-
let cnt = 1;
|
|
378
|
-
for (let i = 0; i < uriArray.length; i += 1) {
|
|
379
|
-
if (uriArray[i].indexOf('{pathv') >= 0) {
|
|
380
|
-
respObjKey = matchResponse(uriPath, method, `WITHPATHV${cnt}`, responseKeys);
|
|
381
|
-
|
|
382
|
-
if (respObjKey !== null) {
|
|
383
|
-
break;
|
|
384
|
-
}
|
|
385
|
-
cnt += 1;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
293
|
+
if (respObjKey === null) {
|
|
294
|
+
const specificResp = transUtilInst.getRespObjKeyFromPath(uriPath, reqPath, callProperties, basepathGl, versionGl, method, true, entitySchema);
|
|
295
|
+
if (specificResp) {
|
|
296
|
+
respObjKey = specificResp.key;
|
|
388
297
|
}
|
|
389
298
|
}
|
|
390
299
|
|
|
391
300
|
// if there are queiries or options, see if there is a specific response for query or options
|
|
392
301
|
if (respObjKey === null && uriPath.indexOf('?') >= 0) {
|
|
393
|
-
|
|
302
|
+
let specificResp = transUtilInst.matchResponse(uriPath, method, 'WITHQUERY', responseKeys, entitySchema.responseDatatype);
|
|
303
|
+
if (specificResp) {
|
|
304
|
+
respObjKey = specificResp.key;
|
|
305
|
+
}
|
|
394
306
|
|
|
395
307
|
if (respObjKey === null) {
|
|
396
|
-
|
|
308
|
+
specificResp = transUtilInst.matchResponse(uriPath, method, 'WITHOPTIONS', responseKeys, entitySchema.responseDatatype);
|
|
309
|
+
if (specificResp) {
|
|
310
|
+
respObjKey = specificResp.key;
|
|
311
|
+
}
|
|
397
312
|
}
|
|
398
313
|
}
|
|
399
314
|
|
|
400
315
|
if (respObjKey === null) {
|
|
401
|
-
|
|
316
|
+
const specificResp = transUtilInst.matchResponse(uriPath, method, 'DEFAULT', responseKeys, entitySchema.responseDatatype);
|
|
317
|
+
if (specificResp) {
|
|
318
|
+
respObjKey = specificResp.key;
|
|
319
|
+
}
|
|
402
320
|
}
|
|
403
321
|
|
|
404
322
|
if (respObjKey === null) {
|
|
@@ -524,6 +442,7 @@ function handleRestRequest(request, entityId, entitySchema, callProperties, filt
|
|
|
524
442
|
return callback(retObject);
|
|
525
443
|
});
|
|
526
444
|
}
|
|
445
|
+
|
|
527
446
|
// process the response - parse it
|
|
528
447
|
try {
|
|
529
448
|
retResponse = JSON.parse(resObj.response.trim());
|
package/lib/throttle.js
CHANGED
|
@@ -442,7 +442,12 @@ function gettingCloseInterval(myRequest, transNum, callback) {
|
|
|
442
442
|
|
|
443
443
|
try {
|
|
444
444
|
let intRun = false;
|
|
445
|
-
|
|
445
|
+
let fastInt = (avgTotal / avgSize) * 0.5;
|
|
446
|
+
|
|
447
|
+
// prevent timeout overflow errors - 15 min max
|
|
448
|
+
if (fastInt > 900000) {
|
|
449
|
+
fastInt = 900000;
|
|
450
|
+
}
|
|
446
451
|
|
|
447
452
|
// rapid inner interval - should be done when it is almost my time to run.
|
|
448
453
|
const intervalObject = setInterval(() => {
|
|
@@ -1128,6 +1133,11 @@ class SystemXThrottle {
|
|
|
1128
1133
|
outerInterval *= 0.95;
|
|
1129
1134
|
}
|
|
1130
1135
|
|
|
1136
|
+
// prevent timeout overflow errors - 2 hours max
|
|
1137
|
+
if (outerInterval > 7200000) {
|
|
1138
|
+
outerInterval = 7200000;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1131
1141
|
log.debug(`${origin}: Request ${queueItem.request_id} Transaction ${queueItem.transNum} Outer Interval set to: ${outerInterval}`);
|
|
1132
1142
|
|
|
1133
1143
|
// outer interval to get a turn request
|
package/lib/translatorUtil.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
/* eslint no-use-before-define: warn */
|
|
8
8
|
/* eslint prefer-object-spread:warn */
|
|
9
9
|
/* eslint prefer-destructuring:warn */
|
|
10
|
+
/* eslint no-continue:warn */
|
|
10
11
|
|
|
11
12
|
/* NodeJS internal utilities */
|
|
12
13
|
const fs = require('fs');
|
|
@@ -17,6 +18,16 @@ const AjvCl = require('ajv');
|
|
|
17
18
|
const jsonQuery = require('json-query');
|
|
18
19
|
const cryptoJS = require('crypto-js');
|
|
19
20
|
|
|
21
|
+
// get global strings
|
|
22
|
+
const { globalStrings } = require(path.join(__dirname, 'constants.js'));
|
|
23
|
+
const { pathVarMarker } = globalStrings;
|
|
24
|
+
const { versionMarker } = globalStrings;
|
|
25
|
+
const { basePathMarker } = globalStrings;
|
|
26
|
+
const { withPathVarPrefix } = globalStrings;
|
|
27
|
+
const { urlSplit } = globalStrings;
|
|
28
|
+
const { pathSplit } = globalStrings;
|
|
29
|
+
const { globalFlag } = globalStrings;
|
|
30
|
+
|
|
20
31
|
let id = null;
|
|
21
32
|
let propUtilInst = null;
|
|
22
33
|
let translator = null;
|
|
@@ -943,6 +954,172 @@ class AdapterTranslatorUtil {
|
|
|
943
954
|
return combinedObj;
|
|
944
955
|
}
|
|
945
956
|
|
|
957
|
+
/**
|
|
958
|
+
* @summary Gets the property from call properties or global
|
|
959
|
+
*
|
|
960
|
+
* @function getPathProperty
|
|
961
|
+
* @param {String} globalProperty - global property value
|
|
962
|
+
* @param {String} propertyName - property name to find it in call properties
|
|
963
|
+
*
|
|
964
|
+
*/
|
|
965
|
+
getPathProperty(globalProperty, propertyName, callProperties) {
|
|
966
|
+
const origin = `${this.myid}-translatorUtil-getPathProperty`;
|
|
967
|
+
log.trace(origin);
|
|
968
|
+
|
|
969
|
+
let propertyValue = `${pathSplit}${globalProperty}`;
|
|
970
|
+
if (callProperties && callProperties[propertyName]) {
|
|
971
|
+
propertyValue = `${pathSplit}${callProperties[propertyName]}`;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
// remove any double slash that we may have introduced - consistency
|
|
975
|
+
return propertyValue.replace(new RegExp(`${pathSplit}${pathSplit}`, globalFlag), pathSplit);
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
/**
|
|
979
|
+
* @summary Matches the response to the response object to get the key
|
|
980
|
+
*
|
|
981
|
+
* @function matchResponse
|
|
982
|
+
* @param {String} uriPath - original path from the entitypath
|
|
983
|
+
* @param {String} method - method for the request
|
|
984
|
+
* @param {String} type - type for the mock response
|
|
985
|
+
* @param {Object} mockresponses - mock response objects
|
|
986
|
+
*
|
|
987
|
+
*/
|
|
988
|
+
matchResponse(uriPath, method, type, mockresponses, respDatatype) {
|
|
989
|
+
const origin = `${this.myid}-translatorUtil-matchResponse`;
|
|
990
|
+
log.trace(origin);
|
|
991
|
+
|
|
992
|
+
// Go through the mock data keys to find the proper data to return
|
|
993
|
+
for (let p = 0; p < mockresponses.length; p += 1) {
|
|
994
|
+
// is this the mock data for this call
|
|
995
|
+
if (Object.hasOwnProperty.call(mockresponses[p], 'name') && uriPath === mockresponses[p].name
|
|
996
|
+
&& Object.hasOwnProperty.call(mockresponses[p], 'method') && method.toUpperCase() === mockresponses[p].method.toUpperCase()
|
|
997
|
+
&& Object.hasOwnProperty.call(mockresponses[p], 'type') && type.toUpperCase() === mockresponses[p].type.toUpperCase()) {
|
|
998
|
+
// This response best matches the request so return the key and data
|
|
999
|
+
const specificResp = {
|
|
1000
|
+
key: '',
|
|
1001
|
+
status: 'success',
|
|
1002
|
+
code: 200,
|
|
1003
|
+
response: {}
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
if (Object.hasOwnProperty.call(mockresponses[p], 'key')) {
|
|
1007
|
+
specificResp.key = mockresponses[p].key;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
if (Object.hasOwnProperty.call(mockresponses[p], 'response')) {
|
|
1011
|
+
// if a status is defined in the response, use it
|
|
1012
|
+
if (Object.hasOwnProperty.call(mockresponses[p].response, 'response')
|
|
1013
|
+
&& Object.hasOwnProperty.call(mockresponses[p].response, 'status')) {
|
|
1014
|
+
specificResp.code = mockresponses[p].response.status;
|
|
1015
|
+
|
|
1016
|
+
if (respDatatype && respDatatype.toUpperCase() === 'XML2JSON') {
|
|
1017
|
+
specificResp.response = mockresponses[p].response.response;
|
|
1018
|
+
} else {
|
|
1019
|
+
specificResp.response = JSON.stringify(mockresponses[p].response.response);
|
|
1020
|
+
}
|
|
1021
|
+
} else if (respDatatype && respDatatype.toUpperCase() === 'XML2JSON') {
|
|
1022
|
+
// if no response field, assume that the entire data is the response
|
|
1023
|
+
specificResp.response = mockresponses[p].response;
|
|
1024
|
+
} else {
|
|
1025
|
+
specificResp.response = JSON.stringify(mockresponses[p].response);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
return specificResp;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
return null;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* @summary Gets the response object key from the path for determining how to match response
|
|
1038
|
+
* This might be used by token calls in the connector so it might be good to move out of here!
|
|
1039
|
+
*
|
|
1040
|
+
* @function getRespObjKeyFromPath
|
|
1041
|
+
* @param {String} uriPath - original path from the entitypath
|
|
1042
|
+
* @param {String} reqPath - path after translations - actual call path
|
|
1043
|
+
* @param {Object} callProperties - properties to override on this call
|
|
1044
|
+
* @param {String} basepathGl - base path global property
|
|
1045
|
+
* @param {String} versionGl - version global property
|
|
1046
|
+
* @param {String} method - method type for the request
|
|
1047
|
+
* @param {bollean} withPath - whether we are checking for with path vars
|
|
1048
|
+
* @param {Object} entitySchema - the entity schema for the request
|
|
1049
|
+
*
|
|
1050
|
+
*/
|
|
1051
|
+
getRespObjKeyFromPath(uriPath, reqPath, callProperties, basepathGl, versionGl, method, withPath, entitySchema) {
|
|
1052
|
+
const origin = `${this.myid}-translatorUtil-getRespObjKeyFromPath`;
|
|
1053
|
+
log.trace(origin);
|
|
1054
|
+
let specificResp = null;
|
|
1055
|
+
|
|
1056
|
+
// if there are path variables, see if there is something that matches a specific variable
|
|
1057
|
+
if (uriPath.indexOf(pathVarMarker) >= 0) {
|
|
1058
|
+
const uriTemp = uriPath.split(urlSplit);
|
|
1059
|
+
const actTemp = reqPath.split(urlSplit);
|
|
1060
|
+
|
|
1061
|
+
// make sure the entitypath has a standard format since they can differ (e.g. slashes or no slashes)
|
|
1062
|
+
uriTemp[0] = uriTemp[0].replace(new RegExp(pathVarMarker, globalFlag), `${pathSplit}${pathVarMarker}`);
|
|
1063
|
+
uriTemp[0] = uriTemp[0].replace(new RegExp(versionMarker, globalFlag), `${pathSplit}${versionMarker}`);
|
|
1064
|
+
uriTemp[0] = uriTemp[0].replace(new RegExp(basePathMarker, globalFlag), `${pathSplit}${basePathMarker}`);
|
|
1065
|
+
uriTemp[0] = uriTemp[0].replace(new RegExp(`${pathSplit}${pathSplit}`, globalFlag), pathSplit);
|
|
1066
|
+
|
|
1067
|
+
// if the original path has {base_path}, remove base_path from both paths
|
|
1068
|
+
if (uriTemp[0].indexOf(basePathMarker) >= 0) {
|
|
1069
|
+
// get rid of base path marker from the original path
|
|
1070
|
+
uriTemp[0] = uriTemp[0].replace(new RegExp(`${pathSplit}${basePathMarker}`, globalFlag), '');
|
|
1071
|
+
// get rid of base path from the request path
|
|
1072
|
+
if (basepathGl && basepathGl !== '/') {
|
|
1073
|
+
actTemp[0] = actTemp[0].replace(this.getPathProperty(basepathGl, 'base_path', callProperties), '');
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
// if the original path has {version}, remove version from both paths
|
|
1078
|
+
if (uriTemp[0].indexOf(versionMarker) >= 0) {
|
|
1079
|
+
// get rid of version marker from the original path
|
|
1080
|
+
uriTemp[0] = uriTemp[0].replace(new RegExp(`${pathSplit}${versionMarker}`, globalFlag), '');
|
|
1081
|
+
// get rid of version from the request path
|
|
1082
|
+
if (versionGl && versionGl !== '/') {
|
|
1083
|
+
actTemp[0] = actTemp[0].replace(this.getPathProperty(versionGl, 'version', callProperties), '');
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
const uriArray = uriTemp[0].split(pathSplit);
|
|
1088
|
+
const actArray = actTemp[0].split(pathSplit);
|
|
1089
|
+
|
|
1090
|
+
// if this is one of the generic requests need to pad the actual array or mock data for specific path variable will not work
|
|
1091
|
+
if (entitySchema.entitypath.indexOf('/{pathv1}/{pathv2}/{pathv3}/{pathv4}/{pathv5}/{pathv6}/{pathv7}/{pathv8}/{pathv9}/{pathv10}/{pathv11}/{pathv12}/{pathv13}/{pathv14}/{pathv15}/{pathv16}/{pathv17}/{pathv18}/{pathv19}/{pathv20}?{query}') >= 0) {
|
|
1092
|
+
for (let e = actArray.length; e < uriArray.length; e += 1) {
|
|
1093
|
+
actArray.push('');
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
// the number of items in both should be the same
|
|
1098
|
+
if (uriArray.length === actArray.length) {
|
|
1099
|
+
let varCount = 1;
|
|
1100
|
+
// want to go through the path to find the path variables
|
|
1101
|
+
for (let i = 0; i < uriArray.length; i += 1) {
|
|
1102
|
+
// if this is a path variable in the original path
|
|
1103
|
+
if (uriArray[i].indexOf(pathVarMarker) >= 0) {
|
|
1104
|
+
// are we checking generic path vars (withPath) or specific path data
|
|
1105
|
+
if (withPath) {
|
|
1106
|
+
specificResp = this.matchResponse(uriPath, method, `${withPathVarPrefix}${varCount}`, entitySchema.mockresponses, entitySchema.responseDatatype);
|
|
1107
|
+
} else {
|
|
1108
|
+
specificResp = this.matchResponse(uriPath, method, actArray[i], entitySchema.mockresponses, entitySchema.responseDatatype);
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
if (specificResp !== null) {
|
|
1112
|
+
break;
|
|
1113
|
+
}
|
|
1114
|
+
varCount += 1;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
return specificResp;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
946
1123
|
/**
|
|
947
1124
|
* @summary If the input is a stringified JSON object, return the JSON object. Otherwise,
|
|
948
1125
|
* return the object that was provided.
|