@itentialopensource/adapter-utils 4.47.0 → 4.48.0

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/CHANGELOG.md CHANGED
@@ -1,4 +1,14 @@
1
1
 
2
+ ## 4.48.0 [08-16-2022]
3
+
4
+ * Changes to support entitypath object with multiple paths
5
+
6
+ Closes ADAPT-2331
7
+
8
+ See merge request itentialopensource/adapter-utils!236
9
+
10
+ ---
11
+
2
12
  ## 4.47.0 [08-13-2022]
3
13
 
4
14
  * Add SSO capability into service instance config
@@ -45,6 +45,7 @@ let host = null;
45
45
  let port = null;
46
46
  let basepath = null;
47
47
  let version = null;
48
+ let choosepath = null;
48
49
  let authMethod = null;
49
50
  let authField = null;
50
51
  let authFormat = null;
@@ -1503,7 +1504,7 @@ function buildTokenRequest(reqPath, reqBody, callProperties, callback) {
1503
1504
 
1504
1505
  try {
1505
1506
  // Get the entity schema from the file system
1506
- return propUtilInst.getEntitySchema('.system', 'getToken', this.dbUtil, (tokenSchema, healthError) => {
1507
+ return propUtilInst.getEntitySchema('.system', 'getToken', choosepath, this.dbUtil, (tokenSchema, healthError) => {
1507
1508
  if (healthError || !tokenSchema || Object.keys(tokenSchema).length === 0) {
1508
1509
  log.debug(`${origin}: Using adapter properties for token information`);
1509
1510
  tokenSchema = null;
@@ -3317,6 +3318,11 @@ class ConnectorRest {
3317
3318
  version = props.version;
3318
3319
  }
3319
3320
 
3321
+ // set the choosepath (optional - default is null)
3322
+ if (typeof props.choosepath === 'string') {
3323
+ choosepath = props.choosepath;
3324
+ }
3325
+
3320
3326
  if (props.authentication) {
3321
3327
  // set the authentication method (required - default is null)
3322
3328
  if (typeof props.authentication.auth_method === 'string') {
@@ -30,7 +30,7 @@ class AdapterPropertyUtil {
30
30
  *
31
31
  * @return {Object} entitySchema - the entity schema object
32
32
  */
33
- getEntitySchemaFromFS(entityName, actionName) {
33
+ getEntitySchemaFromFS(entityName, actionName, choosepath) {
34
34
  const origin = `${this.myid}-propertyUtil-getEntitySchemaFromFS`;
35
35
  log.trace(origin);
36
36
 
@@ -264,6 +264,32 @@ class AdapterPropertyUtil {
264
264
  entitySchema.responseObjects = [];
265
265
  entitySchema.mockresponses = [];
266
266
 
267
+ // if the entitypath is an object instead of a string need to figure out which path to use
268
+ if (actionInfo.entitypath && typeof actionInfo.entitypath === 'object') {
269
+ const ekeys = Object.keys(actionInfo.entitypath);
270
+ if (ekeys.length > 0) {
271
+ // the first one is the default so if we do not have a match that is the one that will be used
272
+ entitySchema.entitypath = actionInfo.entitypath[ekeys[0]];
273
+ for (let ep = 1; ep < ekeys.length; ep += 1) {
274
+ // see if the key matches the choosepath value, if it does set the entitypath
275
+ if (choosepath && ekeys[ep] === choosepath) {
276
+ entitySchema.entitypath = actionInfo.entitypath[ekeys[ep]];
277
+ break;
278
+ }
279
+ }
280
+ } else {
281
+ // add the specific pieces of the error object
282
+ errorObj.type = 'Invalid Action File';
283
+ errorObj.vars = ['missing entity path', actionFile];
284
+
285
+ // log (if not system entity) and throw the error
286
+ if (entityName !== '.system') {
287
+ log.error(`${origin}: Entity ${entityName} action ${actionName} - missing entity path`);
288
+ }
289
+ throw new Error(JSON.stringify(errorObj));
290
+ }
291
+ }
292
+
267
293
  // if info provided, replace the defaults
268
294
  if (actionInfo.querykey) {
269
295
  entitySchema.querykey = actionInfo.querykey;
@@ -399,7 +425,7 @@ class AdapterPropertyUtil {
399
425
  *
400
426
  * @return {Object} entitySchema - the entity schema object
401
427
  */
402
- getEntitySchemaFromDB(dbObj, entityName, actionName, dbUtils, callback) {
428
+ getEntitySchemaFromDB(dbObj, entityName, actionName, choosepath, dbUtils, callback) {
403
429
  const origin = `${this.myid}-propertyUtil-getEntitySchemaFromDB`;
404
430
  log.trace(origin);
405
431
 
@@ -672,6 +698,33 @@ class AdapterPropertyUtil {
672
698
  entitySchema.responseObjects = [];
673
699
  entitySchema.mockresponses = [];
674
700
 
701
+ // if the entitypath is an object instead of a string need to figure out which path to use
702
+ if (actionInfo.entitypath && typeof actionInfo.entitypath === 'object') {
703
+ const ekeys = Object.keys(actionInfo.entitypath);
704
+ if (ekeys.length > 0) {
705
+ // the first one is the default so if we do not have a match that is the one that will be used
706
+ entitySchema.entitypath = actionInfo.entitypath[ekeys[0]];
707
+ for (let ep = 1; ep < ekeys.length; ep += 1) {
708
+ // see if the key matches the choosepath value, if it does set the entitypath
709
+ if (choosepath && ekeys[ep] === choosepath) {
710
+ entitySchema.entitypath = actionInfo.entitypath[ekeys[ep]];
711
+ break;
712
+ }
713
+ }
714
+ } else {
715
+ // add the specific pieces of the error object
716
+ errorObj.type = 'Invalid Action File';
717
+ errorObj.vars = ['missing entity path', entityName];
718
+
719
+ // log (if not system entity) and return the error
720
+ if (entityName !== '.system') {
721
+ log.error(`${origin}: Entity ${entityName} action ${actionName} - missing entity path`);
722
+ errorObj.error = [`${origin}: Entity ${entityName} action ${actionName} - missing entity path`];
723
+ }
724
+ return callback(null, errorObj);
725
+ }
726
+ }
727
+
675
728
  // if info provided, replace the defaults
676
729
  if (actionInfo.querykey) {
677
730
  entitySchema.querykey = actionInfo.querykey;
@@ -796,14 +849,14 @@ class AdapterPropertyUtil {
796
849
  *
797
850
  * @return {Object} entitySchema - the entity schema object
798
851
  */
799
- getEntitySchema(entityName, actionName, dbUtils, callback) {
852
+ getEntitySchema(entityName, actionName, choosepath, dbUtils, callback) {
800
853
  const origin = `${this.myid}-propertyUtil-getEntitySchema`;
801
854
  log.trace(origin);
802
855
 
803
856
  // need to try to get the entity schema from the adapter database
804
857
  try {
805
858
  // call to get the adapter schema from the database
806
- return this.getEntitySchemaFromDB(null, entityName, actionName, dbUtils, (dbresp, dberror) => {
859
+ return this.getEntitySchemaFromDB(null, entityName, actionName, choosepath, dbUtils, (dbresp, dberror) => {
807
860
  // if we got an error back - just means db config not in place
808
861
  if (dberror || !dbresp || (dbresp && Object.keys(dbresp).length === 0)) {
809
862
  log.debug('unable to get adapter config from adapter database');
@@ -816,7 +869,7 @@ class AdapterPropertyUtil {
816
869
  };
817
870
 
818
871
  // need to try to get the entity schema from the iap database
819
- return this.getEntitySchemaFromDB(iapDB, entityName, actionName, dbUtils, (iapdbresp, iapdberror) => {
872
+ return this.getEntitySchemaFromDB(iapDB, entityName, actionName, choosepath, dbUtils, (iapdbresp, iapdberror) => {
820
873
  // if we got an error back - just means db config not in place
821
874
  if (iapdberror || !iapdbresp || (iapdbresp && Object.keys(iapdbresp).length === 0)) {
822
875
  log.debug('unable to get adapter config from iap database');
@@ -824,7 +877,7 @@ class AdapterPropertyUtil {
824
877
  // need to try to get the entity schema from the filesystem
825
878
  log.debug('returning adapter config from file system');
826
879
  try {
827
- return callback(this.getEntitySchemaFromFS(entityName, actionName), null);
880
+ return callback(this.getEntitySchemaFromFS(entityName, actionName, choosepath), null);
828
881
  } catch (exc) {
829
882
  log.error('Exception caught on File System');
830
883
  return callback(null, exc);
@@ -117,6 +117,11 @@ function walkThroughActionFiles(directory) {
117
117
  const actionSchema = JSON.parse(fs.readFileSync(actionSchemaFile, 'utf-8'));
118
118
  const entitydir = `${directory}/entities`;
119
119
 
120
+ // if there is no entity directory - return
121
+ if (!fs.existsSync(directory) || !fs.existsSync(entitydir)) {
122
+ return clean;
123
+ }
124
+
120
125
  // if there is an entity directory
121
126
  if (fs.statSync(directory).isDirectory() && fs.statSync(entitydir).isDirectory()) {
122
127
  const entities = fs.readdirSync(entitydir);
@@ -577,7 +582,7 @@ class RequestHandler {
577
582
  }
578
583
 
579
584
  // Get the entity schema from the file system
580
- return this.propUtil.getEntitySchema(entity, action, this.dbUtil, (entitySchema, entityError) => {
585
+ return this.propUtil.getEntitySchema(entity, action, this.props.choosepath, this.dbUtil, (entitySchema, entityError) => {
581
586
  // verify protocol for call
582
587
  if (entityError) {
583
588
  const errorObj = this.transUtil.checkAndReturn(entityError, origin, 'Issue identifiying request');
@@ -673,7 +678,7 @@ class RequestHandler {
673
678
  let prot = this.props.healthcheck.protocol;
674
679
 
675
680
  // Get the entity schema from the file system
676
- return this.propUtil.getEntitySchema('.system', 'healthcheck', this.dbUtil, (healthSchema, healthError) => {
681
+ return this.propUtil.getEntitySchema('.system', 'healthcheck', this.props.choosepath, this.dbUtil, (healthSchema, healthError) => {
677
682
  if (healthError || !healthSchema || Object.keys(healthSchema).length === 0) {
678
683
  log.debug(`${origin}: Using adapter properties for healthcheck information`);
679
684
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itentialopensource/adapter-utils",
3
- "version": "4.47.0",
3
+ "version": "4.48.0",
4
4
  "description": "Itential Adapter Utility Libraries",
5
5
  "scripts": {
6
6
  "postinstall": "node utils/setup.js",
@@ -32,10 +32,12 @@
32
32
  ]
33
33
  },
34
34
  "entitypath": {
35
- "type": "string",
36
- "description": "the path to use for this action",
37
- "default": "GET",
38
- "pattern": "^({base_path}|\\/)[-a-zA-Z0-9!@$:&%_+.,~#\\/*=:]*({version})?([-a-zA-Z0-9!@$:&%_+.,~#\\/*=:]*({pathv[0-9]+})?)*(\\??[-a-zA-Z0-9!@$:&%_+.,\\(\\)~#\\/*=:]*({username})?[-a-zA-Z0-9!@$:&%_+.,\\(\\)~#\/*=:]*({password})?({query})?)?$",
35
+ "type": [
36
+ "string",
37
+ "object"
38
+ ],
39
+ "description": "the path(s) to use for this action",
40
+ "default": "",
39
41
  "examples": [
40
42
  "/api/devices{pathv1}{query}", "/api/devices{pathv1}/components{pathv2}{query}",
41
43
  "/api/devices", "/api/devices{query}"
@@ -18,6 +18,11 @@
18
18
  "minimum": 1,
19
19
  "maximum": 65535
20
20
  },
21
+ "choosepath": {
22
+ "type": "string",
23
+ "description": "choose the path to use -- requires entityPath choices",
24
+ "default": ""
25
+ },
21
26
  "base_path": {
22
27
  "type": "string",
23
28
  "description": "a base path that is consistent across api calls",
@@ -382,7 +387,8 @@
382
387
  },
383
388
  "query_object": {
384
389
  "type": "object",
385
- "description": "Query object { device: xxxxx } to be placed into the healthcheck, will be converted to query string by the adapter"
390
+ "description": "Query object { device: xxxxx } to be placed into the healthcheck, will be converted to query string by the adapter",
391
+ "default": {}
386
392
  }
387
393
  },
388
394
  "required": [
@@ -462,6 +468,7 @@
462
468
  "priorities": {
463
469
  "type": "array",
464
470
  "description": "define your priorities here",
471
+ "default": [],
465
472
  "items": {
466
473
  "type": "object",
467
474
  "properties": {
@@ -532,6 +539,7 @@
532
539
  "failover_codes": {
533
540
  "type": "array",
534
541
  "description": "An array of codes where it is ok to try another method",
542
+ "default": [],
535
543
  "items": {
536
544
  "type": "integer"
537
545
  }
@@ -549,19 +557,23 @@
549
557
  "properties": {
550
558
  "payload": {
551
559
  "type": "object",
552
- "description": "payload fields that will be appended to the provided payload (excluding GET calls)"
560
+ "description": "payload fields that will be appended to the provided payload (excluding GET calls)",
561
+ "default": {}
553
562
  },
554
563
  "uriOptions": {
555
564
  "type": "object",
556
- "description": "options that will be appended to all GET calls"
565
+ "description": "options that will be appended to all GET calls",
566
+ "default": {}
557
567
  },
558
568
  "addlHeaders": {
559
569
  "type": "object",
560
- "description": "headers that will be appended to the headers for the call"
570
+ "description": "headers that will be appended to the headers for the call",
571
+ "default": {}
561
572
  },
562
573
  "authData": {
563
574
  "type": "object",
564
- "description": "authentication data that will be appended to the payload for authentication calls"
575
+ "description": "authentication data that will be appended to the payload for authentication calls",
576
+ "default": {}
565
577
  }
566
578
  }
567
579
  },