@itentialopensource/adapter-microsoft_graph 1.0.2 → 1.1.1

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 (48) hide show
  1. package/.eslintignore +0 -1
  2. package/.jshintrc +3 -0
  3. package/AUTH.md +20 -16
  4. package/CALLS.md +69 -28
  5. package/CHANGELOG.md +16 -0
  6. package/CONTRIBUTING.md +1 -160
  7. package/ENHANCE.md +2 -2
  8. package/README.md +31 -22
  9. package/SUMMARY.md +2 -2
  10. package/SYSTEMINFO.md +15 -5
  11. package/adapter.js +248 -330
  12. package/adapterBase.js +538 -873
  13. package/changelogs/changelog.md +6 -0
  14. package/entities/Mail/action.json +20 -0
  15. package/entities/Mail/schema.json +1 -0
  16. package/metadata.json +52 -0
  17. package/package.json +22 -25
  18. package/pronghorn.json +550 -144
  19. package/propertiesSchema.json +444 -40
  20. package/refs?service=git-upload-pack +0 -0
  21. package/report/adapter-openapi.json +14709 -0
  22. package/report/adapter-openapi.yaml +9744 -0
  23. package/report/adapterInfo.json +8 -8
  24. package/report/updateReport1691507370664.json +120 -0
  25. package/report/updateReport1692202407231.json +120 -0
  26. package/report/updateReport1694460353234.json +120 -0
  27. package/report/updateReport1695667793473.json +120 -0
  28. package/sampleProperties.json +63 -2
  29. package/test/integration/adapterTestBasicGet.js +1 -1
  30. package/test/integration/adapterTestConnectivity.js +91 -42
  31. package/test/integration/adapterTestIntegration.js +130 -2
  32. package/test/unit/adapterBaseTestUnit.js +395 -292
  33. package/test/unit/adapterTestUnit.js +306 -109
  34. package/utils/adapterInfo.js +1 -1
  35. package/utils/addAuth.js +1 -1
  36. package/utils/artifactize.js +1 -1
  37. package/utils/checkMigrate.js +1 -1
  38. package/utils/entitiesToDB.js +1 -0
  39. package/utils/findPath.js +1 -1
  40. package/utils/methodDocumentor.js +57 -22
  41. package/utils/modify.js +13 -15
  42. package/utils/packModificationScript.js +1 -1
  43. package/utils/taskMover.js +309 -0
  44. package/utils/tbScript.js +3 -10
  45. package/utils/tbUtils.js +2 -3
  46. package/utils/testRunner.js +1 -1
  47. package/utils/troubleshootingAdapter.js +1 -3
  48. package/workflows/README.md +0 -3
package/adapterBase.js CHANGED
@@ -11,14 +11,18 @@
11
11
  /* eslint prefer-destructuring: warn */
12
12
 
13
13
  /* Required libraries. */
14
- const fs = require('fs-extra');
15
14
  const path = require('path');
16
- const jsonQuery = require('json-query');
17
- const EventEmitterCl = require('events').EventEmitter;
18
15
  const { execSync } = require('child_process');
16
+ const { spawnSync } = require('child_process');
17
+ const EventEmitterCl = require('events').EventEmitter;
18
+ const fs = require('fs-extra');
19
+ const jsonQuery = require('json-query');
20
+
21
+ const sampleProperties = require(`${__dirname}/sampleProperties.json`).properties;
19
22
 
20
23
  /* The schema validator */
21
24
  const AjvCl = require('ajv');
25
+ const { Test } = require('mocha');
22
26
 
23
27
  /* Fetch in the other needed components for the this Adaptor */
24
28
  const PropUtilCl = require('@itentialopensource/adapter-utils').PropertyUtility;
@@ -27,8 +31,10 @@ const RequestHandlerCl = require('@itentialopensource/adapter-utils').RequestHan
27
31
  const entitiesToDB = require(path.join(__dirname, 'utils/entitiesToDB'));
28
32
  const troubleshootingAdapter = require(path.join(__dirname, 'utils/troubleshootingAdapter'));
29
33
  const tbUtils = require(path.join(__dirname, 'utils/tbUtils'));
34
+ const taskMover = require(path.join(__dirname, 'utils/taskMover'));
30
35
 
31
36
  let propUtil = null;
37
+ let choosepath = null;
32
38
 
33
39
  /*
34
40
  * INTERNAL FUNCTION: force fail the adapter - generally done to cause restart
@@ -101,7 +107,7 @@ function updateSchema(entityPath, configFile, changes) {
101
107
  /*
102
108
  * INTERNAL FUNCTION: update the mock data file
103
109
  */
104
- function updateMock(mockPath, configFile, changes) {
110
+ function updateMock(mockPath, configFile, changes, replace) {
105
111
  // if the mock file does not exist - create it
106
112
  const mockFile = path.join(mockPath, `/${configFile}`);
107
113
  if (!fs.existsSync(mockFile)) {
@@ -113,7 +119,11 @@ function updateMock(mockPath, configFile, changes) {
113
119
  let mock = require(path.resolve(mockPath, configFile));
114
120
 
115
121
  // merge the changes into the mock file
116
- mock = propUtil.mergeProperties(changes, mock);
122
+ if (replace === true) {
123
+ mock = changes;
124
+ } else {
125
+ mock = propUtil.mergeProperties(changes, mock);
126
+ }
117
127
 
118
128
  fs.writeFileSync(mockFile, JSON.stringify(mock, null, 2));
119
129
  return null;
@@ -145,27 +155,6 @@ function updatePackage(changes) {
145
155
  return null;
146
156
  }
147
157
 
148
- /*
149
- * INTERNAL FUNCTION: get data from source(s) - nested
150
- */
151
- function getDataFromSources(loopField, sources) {
152
- let fieldValue = loopField;
153
-
154
- // go through the sources to find the field
155
- for (let s = 0; s < sources.length; s += 1) {
156
- // find the field value using jsonquery
157
- const nestedValue = jsonQuery(loopField, { data: sources[s] }).value;
158
-
159
- // if we found in source - set and no need to check other sources
160
- if (nestedValue) {
161
- fieldValue = nestedValue;
162
- break;
163
- }
164
- }
165
-
166
- return fieldValue;
167
- }
168
-
169
158
  /* GENERAL ADAPTER FUNCTIONS THESE SHOULD NOT BE DIRECTLY MODIFIED */
170
159
  /* IF YOU NEED MODIFICATIONS, REDEFINE THEM IN adapter.js!!! */
171
160
  class AdapterBase extends EventEmitterCl {
@@ -255,7 +244,7 @@ class AdapterBase extends EventEmitterCl {
255
244
  this.allProps = this.propUtilInst.mergeProperties(properties, defProps);
256
245
 
257
246
  // validate the entity against the schema
258
- const ajvInst = new AjvCl();
247
+ const ajvInst = new AjvCl({ strictSchema: false, allowUnionTypes: true });
259
248
  const validate = ajvInst.compile(propertiesSchema);
260
249
  const result = validate(this.allProps);
261
250
 
@@ -433,6 +422,40 @@ class AdapterBase extends EventEmitterCl {
433
422
  return myfunctions;
434
423
  }
435
424
 
425
+ /**
426
+ * iapGetAdapterWorkflowFunctions is used to get all of the workflow function in the adapter
427
+ * @param {array} ignoreThese - additional methods to ignore (optional)
428
+ *
429
+ * @function iapGetAdapterWorkflowFunctions
430
+ */
431
+ iapGetAdapterWorkflowFunctions(ignoreThese) {
432
+ const myfunctions = this.getAllFunctions();
433
+ const wffunctions = [];
434
+
435
+ // remove the functions that should not be in a Workflow
436
+ for (let m = 0; m < myfunctions.length; m += 1) {
437
+ if (myfunctions[m] === 'checkActionFiles') {
438
+ // got to the second tier (adapterBase)
439
+ break;
440
+ }
441
+ if (!(myfunctions[m].endsWith('Emit') || myfunctions[m].match(/Emit__v[0-9]+/))) {
442
+ let found = false;
443
+ if (ignoreThese && Array.isArray(ignoreThese)) {
444
+ for (let i = 0; i < ignoreThese.length; i += 1) {
445
+ if (myfunctions[m].toUpperCase() === ignoreThese[i].toUpperCase()) {
446
+ found = true;
447
+ }
448
+ }
449
+ }
450
+ if (!found) {
451
+ wffunctions.push(myfunctions[m]);
452
+ }
453
+ }
454
+ }
455
+
456
+ return wffunctions;
457
+ }
458
+
436
459
  /**
437
460
  * checkActionFiles is used to update the validation of the action files.
438
461
  *
@@ -488,40 +511,6 @@ class AdapterBase extends EventEmitterCl {
488
511
  return this.requestHandlerInst.encryptProperty(property, technique, callback);
489
512
  }
490
513
 
491
- /**
492
- * iapGetAdapterWorkflowFunctions is used to get all of the workflow function in the adapter
493
- * @param {array} ignoreThese - additional methods to ignore (optional)
494
- *
495
- * @function iapGetAdapterWorkflowFunctions
496
- */
497
- iapGetAdapterWorkflowFunctions(ignoreThese) {
498
- const myfunctions = this.getAllFunctions();
499
- const wffunctions = [];
500
-
501
- // remove the functions that should not be in a Workflow
502
- for (let m = 0; m < myfunctions.length; m += 1) {
503
- if (myfunctions[m] === 'addEntityCache') {
504
- // got to the second tier (adapterBase)
505
- break;
506
- }
507
- if (!(myfunctions[m].endsWith('Emit') || myfunctions[m].match(/Emit__v[0-9]+/))) {
508
- let found = false;
509
- if (ignoreThese && Array.isArray(ignoreThese)) {
510
- for (let i = 0; i < ignoreThese.length; i += 1) {
511
- if (myfunctions[m].toUpperCase() === ignoreThese[i].toUpperCase()) {
512
- found = true;
513
- }
514
- }
515
- }
516
- if (!found) {
517
- wffunctions.push(myfunctions[m]);
518
- }
519
- }
520
- }
521
-
522
- return wffunctions;
523
- }
524
-
525
514
  /**
526
515
  * iapUpdateAdapterConfiguration is used to update any of the adapter configuration files. This
527
516
  * allows customers to make changes to adapter configuration without having to be on the
@@ -533,16 +522,17 @@ class AdapterBase extends EventEmitterCl {
533
522
  * @param {string} entity - the entity to be changed, if an action, schema or mock data file (optional)
534
523
  * @param {string} type - the type of entity file to change, (action, schema, mock) (optional)
535
524
  * @param {string} action - the action to be changed, if an action, schema or mock data file (optional)
525
+ * @param {boolean} replace - true to replace entire mock data, false to merge/append (optional)
536
526
  * @param {Callback} callback - The results of the call
537
527
  */
538
- iapUpdateAdapterConfiguration(configFile, changes, entity, type, action, callback) {
528
+ iapUpdateAdapterConfiguration(configFile, changes, entity, type, action, replace, callback) {
539
529
  const meth = 'adapterBase-iapUpdateAdapterConfiguration';
540
530
  const origin = `${this.id}-${meth}`;
541
531
  log.trace(origin);
542
532
 
543
533
  // verify the parameters are valid
544
534
  if (changes === undefined || changes === null || typeof changes !== 'object'
545
- || Object.keys(changes).length === 0) {
535
+ || Object.keys(changes).length === 0) {
546
536
  const result = {
547
537
  response: 'No configuration updates to make'
548
538
  };
@@ -627,8 +617,14 @@ class AdapterBase extends EventEmitterCl {
627
617
  if (!fs.existsSync(mpath)) {
628
618
  fs.mkdirSync(mpath);
629
619
  }
620
+ // this means we are changing a mock data file so replace is required
621
+ if (replace === undefined || replace === null || replace === '') {
622
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['replace'], null, null, null);
623
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
624
+ return callback(null, errorObj);
625
+ }
626
+ const mres = updateMock(mpath, configFile, changes, replace);
630
627
 
631
- const mres = updateMock(mpath, configFile, changes);
632
628
  if (mres) {
633
629
  const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Incomplete Configuration Change: ${mres}`, [], null, null, null);
634
630
  log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
@@ -645,6 +641,86 @@ class AdapterBase extends EventEmitterCl {
645
641
  return callback(null, errorObj);
646
642
  }
647
643
 
644
+ /**
645
+ * @summary Suspends the adapter
646
+ * @param {Callback} callback - The adapater suspension status
647
+ * @function iapSuspendAdapter
648
+ */
649
+ iapSuspendAdapter(mode, callback) {
650
+ const origin = `${this.id}-adapterBase-iapSuspendAdapter`;
651
+ if (this.suspended) {
652
+ throw new Error(`${origin}: Adapter is already suspended`);
653
+ }
654
+ try {
655
+ this.suspended = true;
656
+ this.suspendMode = mode;
657
+ if (this.suspendMode === 'pause') {
658
+ const props = JSON.parse(JSON.stringify(this.initProps));
659
+ // To suspend adapter, enable throttling and set concurrent max to 0
660
+ props.throttle.throttle_enabled = true;
661
+ props.throttle.concurrent_max = 0;
662
+ this.refreshProperties(props);
663
+ }
664
+ return callback({ suspended: true });
665
+ } catch (error) {
666
+ return callback(null, error);
667
+ }
668
+ }
669
+
670
+ /**
671
+ * @summary Unsuspends the adapter
672
+ * @param {Callback} callback - The adapater suspension status
673
+ *
674
+ * @function iapUnsuspendAdapter
675
+ */
676
+ iapUnsuspendAdapter(callback) {
677
+ const origin = `${this.id}-adapterBase-iapUnsuspendAdapter`;
678
+ if (!this.suspended) {
679
+ throw new Error(`${origin}: Adapter is not suspended`);
680
+ }
681
+ if (this.suspendMode === 'pause') {
682
+ const props = JSON.parse(JSON.stringify(this.initProps));
683
+ // To unsuspend adapter, keep throttling enabled and begin processing queued requests in order
684
+ props.throttle.throttle_enabled = true;
685
+ props.throttle.concurrent_max = 1;
686
+ this.refreshProperties(props);
687
+ setTimeout(() => {
688
+ this.getQueue((q, error) => {
689
+ // console.log("Items in queue: " + String(q.length))
690
+ if (q.length === 0) {
691
+ // if queue is empty, return to initial properties state
692
+ this.refreshProperties(this.initProps);
693
+ this.suspended = false;
694
+ return callback({ suspended: false });
695
+ }
696
+ // recursive call to check queue again every second
697
+ return this.iapUnsuspendAdapter(callback);
698
+ });
699
+ }, 1000);
700
+ } else {
701
+ this.suspended = false;
702
+ callback({ suspend: false });
703
+ }
704
+ }
705
+
706
+ /**
707
+ * iapGetAdapterQueue is used to get information for all of the requests currently in the queue.
708
+ *
709
+ * @function iapGetAdapterQueue
710
+ * @param {Callback} callback - a callback function to return the result (Queue) or the error
711
+ */
712
+ iapGetAdapterQueue(callback) {
713
+ const origin = `${this.id}-adapterBase-iapGetAdapterQueue`;
714
+ log.trace(origin);
715
+
716
+ return this.requestHandlerInst.getQueue(callback);
717
+ }
718
+
719
+ /* ********************************************** */
720
+ /* */
721
+ /* EXPOSES ADAPTER SCRIPTS */
722
+ /* */
723
+ /* ********************************************** */
648
724
  /**
649
725
  * See if the API path provided is found in this adapter
650
726
  *
@@ -665,6 +741,10 @@ class AdapterBase extends EventEmitterCl {
665
741
  return callback(null, result);
666
742
  }
667
743
 
744
+ if (typeof this.allProps.choosepath === 'string') {
745
+ choosepath = this.allProps.choosepath;
746
+ }
747
+
668
748
  // make sure the entities directory exists
669
749
  const entitydir = path.join(__dirname, 'entities');
670
750
  if (!fs.statSync(entitydir).isDirectory()) {
@@ -689,7 +769,25 @@ class AdapterBase extends EventEmitterCl {
689
769
 
690
770
  // go through all of the actions set the appropriate info in the newActions
691
771
  for (let a = 0; a < actions.actions.length; a += 1) {
692
- if (actions.actions[a].entitypath.indexOf(apiPath) >= 0) {
772
+ if (actions.actions[a].entitypath && typeof actions.actions[a].entitypath === 'object') {
773
+ const entityKeys = Object.keys(actions.actions[a].entitypath);
774
+ if (entityKeys.length > 0) {
775
+ for (let entityKey = 0; entityKey < entityKeys.length; entityKey += 1) {
776
+ if (choosepath && entityKeys[entityKey] === choosepath && actions.actions[a].entitypath[entityKeys[entityKey]].indexOf(apiPath) >= 0) {
777
+ log.info(` Found - entity: ${entities[e]} action: ${actions.actions[a].name}`);
778
+ log.info(` method: ${actions.actions[a].method} path: ${actions.actions[a].entitypath[entityKeys[entityKey]]}`);
779
+ const fitem = {
780
+ entity: entities[e],
781
+ action: actions.actions[a].name,
782
+ method: actions.actions[a].method,
783
+ path: actions.actions[a].entitypath[entityKeys[entityKey]]
784
+ };
785
+ fitems.push(fitem);
786
+ break;
787
+ }
788
+ }
789
+ }
790
+ } else if (actions.actions[a].entitypath.indexOf(apiPath) >= 0) {
693
791
  log.info(` Found - entity: ${entities[e]} action: ${actions.actions[a].name}`);
694
792
  log.info(` method: ${actions.actions[a].method} path: ${actions.actions[a].entitypath}`);
695
793
  const fitem = {
@@ -728,81 +826,6 @@ class AdapterBase extends EventEmitterCl {
728
826
  return callback(result, null);
729
827
  }
730
828
 
731
- /**
732
- * @summary Suspends the adapter
733
- * @param {Callback} callback - The adapater suspension status
734
- * @function iapSuspendAdapter
735
- */
736
- iapSuspendAdapter(mode, callback) {
737
- const origin = `${this.id}-adapterBase-iapSuspendAdapter`;
738
- if (this.suspended) {
739
- throw new Error(`${origin}: Adapter is already suspended`);
740
- }
741
- try {
742
- this.suspended = true;
743
- this.suspendMode = mode;
744
- if (this.suspendMode === 'pause') {
745
- const props = JSON.parse(JSON.stringify(this.initProps));
746
- // To suspend adapter, enable throttling and set concurrent max to 0
747
- props.throttle.throttle_enabled = true;
748
- props.throttle.concurrent_max = 0;
749
- this.refreshProperties(props);
750
- }
751
- return callback({ suspended: true });
752
- } catch (error) {
753
- return callback(null, error);
754
- }
755
- }
756
-
757
- /**
758
- * @summary Unsuspends the adapter
759
- * @param {Callback} callback - The adapater suspension status
760
- *
761
- * @function iapUnsuspendAdapter
762
- */
763
- iapUnsuspendAdapter(callback) {
764
- const origin = `${this.id}-adapterBase-iapUnsuspendAdapter`;
765
- if (!this.suspended) {
766
- throw new Error(`${origin}: Adapter is not suspended`);
767
- }
768
- if (this.suspendMode === 'pause') {
769
- const props = JSON.parse(JSON.stringify(this.initProps));
770
- // To unsuspend adapter, keep throttling enabled and begin processing queued requests in order
771
- props.throttle.throttle_enabled = true;
772
- props.throttle.concurrent_max = 1;
773
- this.refreshProperties(props);
774
- setTimeout(() => {
775
- this.getQueue((q, error) => {
776
- // console.log("Items in queue: " + String(q.length))
777
- if (q.length === 0) {
778
- // if queue is empty, return to initial properties state
779
- this.refreshProperties(this.initProps);
780
- this.suspended = false;
781
- return callback({ suspended: false });
782
- }
783
- // recursive call to check queue again every second
784
- return this.iapUnsuspendAdapter(callback);
785
- });
786
- }, 1000);
787
- } else {
788
- this.suspended = false;
789
- callback({ suspend: false });
790
- }
791
- }
792
-
793
- /**
794
- * iapGetAdapterQueue is used to get information for all of the requests currently in the queue.
795
- *
796
- * @function iapGetAdapterQueue
797
- * @param {Callback} callback - a callback function to return the result (Queue) or the error
798
- */
799
- iapGetAdapterQueue(callback) {
800
- const origin = `${this.id}-adapterBase-iapGetAdapterQueue`;
801
- log.trace(origin);
802
-
803
- return this.requestHandlerInst.getQueue(callback);
804
- }
805
-
806
829
  /**
807
830
  * @summary runs troubleshoot scripts for adapter
808
831
  *
@@ -904,156 +927,89 @@ class AdapterBase extends EventEmitterCl {
904
927
  }
905
928
 
906
929
  /**
907
- * @summary take the entities and add them to the cache
930
+ * @function iapDeactivateTasks
908
931
  *
909
- * @function addEntityCache
910
- * @param {String} entityType - the type of the entities
911
- * @param {Array} data - the list of entities
912
- * @param {String} key - unique key for the entities
913
- *
914
- * @param {Callback} callback - An array of whether the adapter can has the
915
- * desired capability or an error
932
+ * @param {Array} tasks - List of tasks to deactivate
933
+ * @param {Callback} callback
916
934
  */
917
- addEntityCache(entityType, entities, key, callback) {
918
- const meth = 'adapterBase-addEntityCache';
935
+ iapDeactivateTasks(tasks, callback) {
936
+ const meth = 'adapterBase-iapDeactivateTasks';
919
937
  const origin = `${this.id}-${meth}`;
920
938
  log.trace(origin);
921
-
922
- // list containing the items to add to the cache
923
- const entityIds = [];
924
-
925
- if (entities && Object.hasOwnProperty.call(entities, 'response')
926
- && Array.isArray(entities.response)) {
927
- for (let e = 0; e < entities.response.length; e += 1) {
928
- entityIds.push(entities.response[e][key]);
929
- }
939
+ let data;
940
+ try {
941
+ data = taskMover.deactivateTasks(__dirname, tasks);
942
+ } catch (ex) {
943
+ taskMover.rollbackChanges(__dirname);
944
+ taskMover.deleteBackups(__dirname);
945
+ return callback(null, ex);
930
946
  }
931
-
932
- // add the entities to the cache
933
- return this.requestHandlerInst.addEntityCache(entityType, entityIds, (loaded, error) => {
934
- if (error) {
935
- return callback(null, error);
936
- }
937
- if (!loaded) {
938
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Entity Cache Not Loading', [entityType], null, null, null);
939
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
940
- return callback(null, errorObj);
941
- }
942
-
943
- return callback(loaded);
944
- });
947
+ taskMover.deleteBackups(__dirname);
948
+ return callback(data, null);
945
949
  }
946
950
 
947
951
  /**
948
- * @summary sees if the entity is in the entity list or not
952
+ * @function iapActivateTasks
949
953
  *
950
- * @function entityInList
951
- * @param {String/Array} entityId - the specific entity we are looking for
952
- * @param {Array} data - the list of entities
953
- *
954
- * @param {Callback} callback - An array of whether the adapter can has the
955
- * desired capability or an error
954
+ * @param {Array} tasks - List of tasks to deactivate
955
+ * @param {Callback} callback
956
956
  */
957
- entityInList(entityId, data) {
958
- const origin = `${this.id}-adapterBase-entityInList`;
957
+ iapActivateTasks(tasks, callback) {
958
+ const meth = 'adapterBase-iapActivateTasks';
959
+ const origin = `${this.id}-${meth}`;
959
960
  log.trace(origin);
960
-
961
- // need to check on the entities that were passed in
962
- if (Array.isArray(entityId)) {
963
- const resEntity = [];
964
-
965
- for (let e = 0; e < entityId.length; e += 1) {
966
- if (data.includes(entityId[e])) {
967
- resEntity.push(true);
968
- } else {
969
- resEntity.push(false);
970
- }
971
- }
972
-
973
- return resEntity;
961
+ let data;
962
+ try {
963
+ data = taskMover.activateTasks(__dirname, tasks);
964
+ } catch (ex) {
965
+ taskMover.rollbackChanges(__dirname);
966
+ taskMover.deleteBackups(__dirname);
967
+ return callback(null, ex);
974
968
  }
975
-
976
- // does the entity list include the specific entity
977
- return [data.includes(entityId)];
969
+ taskMover.deleteBackups(__dirname);
970
+ return callback(data, null);
978
971
  }
979
972
 
973
+ /* ********************************************** */
974
+ /* */
975
+ /* EXPOSES CACHE CALLS */
976
+ /* */
977
+ /* ********************************************** */
980
978
  /**
981
- * @summary prepare results for verify capability so they are true/false
979
+ * @summary Populate the cache for the given entities
982
980
  *
983
- * @function capabilityResults
984
- * @param {Array} results - the results from the capability check
985
- *
986
- * @param {Callback} callback - An array of whether the adapter can has the
987
- * desired capability or an error
981
+ * @function iapPopulateEntityCache
982
+ * @param {String/Array of Strings} entityType - the entity type(s) to populate
983
+ * @param {Callback} callback - whether the cache was updated or not for each entity type
984
+ * @returns return of the callback
988
985
  */
989
- capabilityResults(results, callback) {
990
- const meth = 'adapterBase-capabilityResults';
991
- const origin = `${this.id}-${meth}`;
986
+ iapPopulateEntityCache(entityTypes, callback) {
987
+ const origin = `${this.myid}-adapterBase-iapPopulateEntityCache`;
992
988
  log.trace(origin);
993
- let locResults = results;
994
-
995
- if (locResults && locResults[0] === 'needupdate') {
996
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Entity Cache Not Loading', ['unknown'], null, null, null);
997
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
998
- this.repeatCacheCount += 1;
999
- return callback(null, errorObj);
1000
- }
1001
989
 
1002
- // if an error occured, return the error
1003
- if (locResults && locResults[0] === 'error') {
1004
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Error Verifying Entity Cache', null, null, null, null);
1005
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1006
- return callback(null, errorObj);
1007
- }
1008
-
1009
- // go through the response and change to true/false
1010
- if (locResults) {
1011
- // if not an array, just convert the return
1012
- if (!Array.isArray(locResults)) {
1013
- if (locResults === 'found') {
1014
- locResults = [true];
1015
- } else {
1016
- locResults = [false];
1017
- }
1018
- } else {
1019
- const temp = [];
1020
-
1021
- // go through each element in the array to convert
1022
- for (let r = 0; r < locResults.length; r += 1) {
1023
- if (locResults[r] === 'found') {
1024
- temp.push(true);
1025
- } else {
1026
- temp.push(false);
1027
- }
1028
- }
1029
- locResults = temp;
1030
- }
1031
- }
1032
-
1033
- // return the results
1034
- return callback(locResults);
990
+ return this.requestHandlerInst.populateEntityCache(entityTypes, callback);
1035
991
  }
1036
992
 
1037
993
  /**
1038
- * @summary Provides a way for the adapter to tell north bound integrations
1039
- * all of the capabilities for the current adapter
994
+ * @summary Retrieves data from cache for specified entity type
1040
995
  *
1041
- * @function getAllCapabilities
1042
- *
1043
- * @return {Array} - containing the entities and the actions available on each entity
996
+ * @function iapRetrieveEntitiesCache
997
+ * @param {String} entityType - entity of which to retrieve
998
+ * @param {Object} options - settings of which data to return and how to return it
999
+ * @param {Callback} callback - the data if it was retrieved
1044
1000
  */
1045
- getAllCapabilities() {
1046
- const origin = `${this.id}-adapterBase-getAllCapabilities`;
1001
+ iapRetrieveEntitiesCache(entityType, options, callback) {
1002
+ const origin = `${this.myid}-adapterBase-iapRetrieveEntitiesCache`;
1047
1003
  log.trace(origin);
1048
1004
 
1049
- // validate the capabilities for the adapter
1050
- try {
1051
- return this.requestHandlerInst.getAllCapabilities();
1052
- } catch (e) {
1053
- return [];
1054
- }
1005
+ return this.requestHandlerInst.retrieveEntitiesCache(entityType, options, callback);
1055
1006
  }
1056
1007
 
1008
+ /* ********************************************** */
1009
+ /* */
1010
+ /* EXPOSES BROKER CALLS */
1011
+ /* */
1012
+ /* ********************************************** */
1057
1013
  /**
1058
1014
  * @summary Determines if this adapter supports any in a list of entities
1059
1015
  *
@@ -1065,396 +1021,61 @@ class AdapterBase extends EventEmitterCl {
1065
1021
  * value is true or false
1066
1022
  */
1067
1023
  hasEntities(entityType, entityList, callback) {
1068
- const origin = `${this.id}-adapter-hasEntities`;
1024
+ const origin = `${this.id}-adapterBase-hasEntities`;
1069
1025
  log.trace(origin);
1070
1026
 
1071
- switch (entityType) {
1072
- case 'Device':
1073
- return this.hasDevices(entityList, callback);
1074
- default:
1075
- return callback(null, `${this.id} does not support entity ${entityType}`);
1076
- }
1027
+ return this.requestHandlerInst.hasEntities(entityType, entityList, callback);
1077
1028
  }
1078
1029
 
1079
1030
  /**
1080
- * @summary Helper method for hasEntities for the specific device case
1031
+ * @summary Determines if this adapter supports any in a list of entities
1032
+ *
1033
+ * @function hasEntitiesAuth
1034
+ * @param {String} entityType - the entity type to check for
1035
+ * @param {Array} entityList - the list of entities we are looking for
1036
+ * @param {Object} callOptions - Additional options used to make request, including auth headers, AWS service, or datatypes
1081
1037
  *
1082
- * @param {Array} deviceList - array of unique device identifiers
1083
- * @param {Callback} callback - A map where the device is the key and the
1038
+ * @param {Callback} callback - A map where the entity is the key and the
1084
1039
  * value is true or false
1085
1040
  */
1086
- hasDevices(deviceList, callback) {
1087
- const origin = `${this.id}-adapter-hasDevices`;
1041
+ hasEntitiesAuth(entityType, entityList, callOptions, callback) {
1042
+ const origin = `${this.id}-adapterBase-hasEntitiesAuth`;
1088
1043
  log.trace(origin);
1089
1044
 
1090
- const findings = deviceList.reduce((map, device) => {
1091
- // eslint-disable-next-line no-param-reassign
1092
- map[device] = false;
1093
- log.debug(`In reduce: ${JSON.stringify(map)}`);
1094
- return map;
1095
- }, {});
1096
- const apiCalls = deviceList.map((device) => new Promise((resolve) => {
1097
- this.getDevice(device, (result, error) => {
1098
- if (error) {
1099
- log.debug(`In map error: ${JSON.stringify(device)}`);
1100
- return resolve({ name: device, found: false });
1101
- }
1102
- log.debug(`In map: ${JSON.stringify(device)}`);
1103
- return resolve({ name: device, found: true });
1104
- });
1105
- }));
1106
- Promise.all(apiCalls).then((results) => {
1107
- results.forEach((device) => {
1108
- findings[device.name] = device.found;
1109
- });
1110
- log.debug(`FINDINGS: ${JSON.stringify(findings)}`);
1111
- return callback(findings);
1112
- }).catch((errors) => {
1113
- log.error('Unable to do device lookup.');
1114
- return callback(null, { code: 503, message: 'Unable to do device lookup.', error: errors });
1115
- });
1045
+ return this.requestHandlerInst.hasEntitiesAuth(entityType, entityList, callOptions, callback);
1116
1046
  }
1117
1047
 
1118
1048
  /**
1119
- * @summary Make one of the needed Broker calls - could be one of many
1049
+ * @summary Get Appliance that match the deviceName
1120
1050
  *
1121
- * @function iapMakeBrokerCall
1122
- * @param {string} brokCall - the name of the broker call (required)
1123
- * @param {object} callProps - the proeprties for the broker call (required)
1124
- * @param {object} devResp - the device details to extract needed inputs (required)
1125
- * @param {string} filterName - any filter to search on (required)
1051
+ * @function getDevice
1052
+ * @param {String} deviceName - the deviceName to find (required)
1126
1053
  *
1127
- * @param {getCallback} callback - a callback function to return the result of the call
1054
+ * @param {getCallback} callback - a callback function to return the result
1055
+ * (appliance) or the error
1128
1056
  */
1129
- iapMakeBrokerCall(brokCall, callProps, devResp, filterName, callback) {
1130
- const meth = 'adapterBase-iapMakeBrokerCall';
1131
- const origin = `${this.id}-${meth}`;
1057
+ getDevice(deviceName, callback) {
1058
+ const origin = `${this.id}-adapterBase-getDevice`;
1132
1059
  log.trace(origin);
1133
1060
 
1134
- try {
1135
- let uriPath = '';
1136
- let uriMethod = 'GET';
1137
- let callQuery = {};
1138
- let callBody = {};
1139
- let callHeaders = {};
1140
- let handleFail = 'fail';
1141
- let ostypePrefix = '';
1142
- let statusValue = 'true';
1143
- if (callProps.path) {
1144
- uriPath = `${callProps.path}`;
1145
-
1146
- // make any necessary changes to the path
1147
- if (devResp !== null && callProps.requestFields && Object.keys(callProps.requestFields).length > 0) {
1148
- const rqKeys = Object.keys(callProps.requestFields);
1149
-
1150
- // get the field from the provided device
1151
- for (let rq = 0; rq < rqKeys.length; rq += 1) {
1152
- const fieldValue = getDataFromSources(callProps.requestFields[rqKeys[rq]], devResp);
1153
-
1154
- // put the value into the path - if it has been specified in the path
1155
- uriPath = uriPath.replace(`{${rqKeys[rq]}}`, fieldValue);
1156
- }
1157
- }
1158
- }
1159
- if (callProps.method) {
1160
- uriMethod = callProps.method;
1161
- }
1162
- if (callProps.query) {
1163
- callQuery = callProps.query;
1164
-
1165
- // go through the query params to check for variable values
1166
- const cpKeys = Object.keys(callQuery);
1167
- for (let cp = 0; cp < cpKeys.length; cp += 1) {
1168
- if (callQuery[cpKeys[cp]].startsWith('{') && callQuery[cpKeys[cp]].endsWith('}')) {
1169
- // make any necessary changes to the query params
1170
- if (devResp !== null && callProps.requestFields && Object.keys(callProps.requestFields).length > 0) {
1171
- const rqKeys = Object.keys(callProps.requestFields);
1172
-
1173
- // get the field from the provided device
1174
- for (let rq = 0; rq < rqKeys.length; rq += 1) {
1175
- if (cpKeys[cp] === rqKeys[rq]) {
1176
- const fieldValue = getDataFromSources(callProps.requestFields[rqKeys[rq]], devResp);
1177
-
1178
- // put the value into the query - if it has been specified in the query
1179
- callQuery[cpKeys[cp]] = fieldValue;
1180
- }
1181
- }
1182
- }
1183
- }
1184
- }
1185
- }
1186
- if (callProps.body) {
1187
- callBody = callProps.body;
1188
-
1189
- // go through the body fields to check for variable values
1190
- const cbKeys = Object.keys(callBody);
1191
- for (let cb = 0; cb < cbKeys.length; cb += 1) {
1192
- if (callBody[cbKeys[cb]].startsWith('{') && callBody[cbKeys[cb]].endsWith('}')) {
1193
- // make any necessary changes to the query params
1194
- if (devResp !== null && callProps.requestFields && Object.keys(callProps.requestFields).length > 0) {
1195
- const rqKeys = Object.keys(callProps.requestFields);
1196
-
1197
- // get the field from the provided device
1198
- for (let rq = 0; rq < rqKeys.length; rq += 1) {
1199
- if (cbKeys[cb] === rqKeys[rq]) {
1200
- const fieldValue = getDataFromSources(callProps.requestFields[rqKeys[rq]], devResp);
1201
-
1202
- // put the value into the query - if it has been specified in the query
1203
- callBody[cbKeys[cb]] = fieldValue;
1204
- }
1205
- }
1206
- }
1207
- }
1208
- }
1209
- }
1210
- if (callProps.headers) {
1211
- callHeaders = callProps.headers;
1212
-
1213
- // go through the body fields to check for variable values
1214
- const chKeys = Object.keys(callHeaders);
1215
- for (let ch = 0; ch < chKeys.length; ch += 1) {
1216
- if (callHeaders[chKeys[ch]].startsWith('{') && callHeaders[chKeys[ch]].endsWith('}')) {
1217
- // make any necessary changes to the query params
1218
- if (devResp !== null && callProps.requestFields && Object.keys(callProps.requestFields).length > 0) {
1219
- const rqKeys = Object.keys(callProps.requestFields);
1220
-
1221
- // get the field from the provided device
1222
- for (let rq = 0; rq < rqKeys.length; rq += 1) {
1223
- if (chKeys[ch] === rqKeys[rq]) {
1224
- const fieldValue = getDataFromSources(callProps.requestFields[rqKeys[rq]], devResp);
1225
-
1226
- // put the value into the query - if it has been specified in the query
1227
- callHeaders[chKeys[ch]] = fieldValue;
1228
- }
1229
- }
1230
- }
1231
- }
1232
- }
1233
- }
1234
- if (callProps.handleFailure) {
1235
- handleFail = callProps.handleFailure;
1236
- }
1237
- if (callProps.responseFields && callProps.responseFields.ostypePrefix) {
1238
- ostypePrefix = callProps.responseFields.ostypePrefix;
1239
- }
1240
- if (callProps.responseFields && callProps.responseFields.statusValue) {
1241
- statusValue = callProps.responseFields.statusValue;
1242
- }
1243
-
1244
- // !! using Generic makes it easier on the Adapter Builder (just need to change the path)
1245
- // !! you can also replace with a specific call if that is easier
1246
- return this.genericAdapterRequest(uriPath, uriMethod, callQuery, callBody, callHeaders, (result, error) => {
1247
- // if we received an error or their is no response on the results return an error
1248
- if (error) {
1249
- if (handleFail === 'fail') {
1250
- return callback(null, error);
1251
- }
1252
- return callback({}, null);
1253
- }
1254
- if (!result.response) {
1255
- if (handleFail === 'fail') {
1256
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', [brokCall], null, null, null);
1257
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1258
- return callback(null, errorObj);
1259
- }
1260
- return callback({}, null);
1261
- }
1262
-
1263
- // get the response piece we care about from the response
1264
- const myResult = result;
1265
- if (callProps.responseDatakey) {
1266
- myResult.response = jsonQuery(callProps.responseDatakey, { data: myResult.response }).value;
1267
- }
1268
-
1269
- // get the keys for the response fields
1270
- let rfKeys = [];
1271
- if (callProps.responseFields && Object.keys(callProps.responseFields).length > 0) {
1272
- rfKeys = Object.keys(callProps.responseFields);
1273
- }
1274
-
1275
- // if we got an array returned (e.g. getDevicesFitered)
1276
- if (Array.isArray(myResult.response)) {
1277
- const listDevices = [];
1278
- for (let a = 0; a < myResult.response.length; a += 1) {
1279
- const thisDevice = myResult.response[a];
1280
- for (let rf = 0; rf < rfKeys.length; rf += 1) {
1281
- if (rfKeys[rf] !== 'ostypePrefix') {
1282
- let fieldValue = getDataFromSources(callProps.responseFields[rfKeys[rf]], [thisDevice, devResp, callProps.requestFields]);
1283
-
1284
- // if the field is ostype - need to add prefix
1285
- if (rfKeys[rf] === 'ostype' && typeof fieldValue === 'string') {
1286
- fieldValue = ostypePrefix + fieldValue;
1287
- }
1288
- // if there is a status to set, set it
1289
- if (rfKeys[rf] === 'status') {
1290
- // if really looking for just a good response
1291
- if (callProps.responseFields[rfKeys[rf]] === 'return2xx' && myResult.icode === statusValue.toString()) {
1292
- thisDevice.isAlive = true;
1293
- } else if (fieldValue.toString() === statusValue.toString()) {
1294
- thisDevice.isAlive = true;
1295
- } else {
1296
- thisDevice.isAlive = false;
1297
- }
1298
- }
1299
- // if we found a good value
1300
- thisDevice[rfKeys[rf]] = fieldValue;
1301
- }
1302
- }
1303
-
1304
- // if there is no filter - add the device to the list
1305
- if (!filterName || filterName.length === 0) {
1306
- listDevices.push(thisDevice);
1307
- } else {
1308
- // if we have to match a filter
1309
- let found = false;
1310
- for (let f = 0; f < filterName.length; f += 1) {
1311
- if (thisDevice.name.indexOf(filterName[f]) >= 0) {
1312
- found = true;
1313
- break;
1314
- }
1315
- }
1316
- // matching device
1317
- if (found) {
1318
- listDevices.push(thisDevice);
1319
- }
1320
- }
1321
- }
1322
-
1323
- // return the array of devices
1324
- return callback(listDevices, null);
1325
- }
1326
-
1327
- // if this is not an array - just about everything else, just handle as a single object
1328
- let thisDevice = myResult.response;
1329
- for (let rf = 0; rf < rfKeys.length; rf += 1) {
1330
- // skip ostypePrefix since it is not a field
1331
- if (rfKeys[rf] !== 'ostypePrefix') {
1332
- let fieldValue = getDataFromSources(callProps.responseFields[rfKeys[rf]], [thisDevice, devResp, callProps.requestFields]);
1333
-
1334
- // if the field is ostype - need to add prefix
1335
- if (rfKeys[rf] === 'ostype' && typeof fieldValue === 'string') {
1336
- fieldValue = ostypePrefix + fieldValue;
1337
- }
1338
- // if there is a status to set, set it
1339
- if (rfKeys[rf] === 'status') {
1340
- // if really looking for just a good response
1341
- if (callProps.responseFields[rfKeys[rf]] === 'return2xx' && myResult.icode === statusValue.toString()) {
1342
- thisDevice.isAlive = true;
1343
- } else if (fieldValue.toString() === statusValue.toString()) {
1344
- thisDevice.isAlive = true;
1345
- } else {
1346
- thisDevice.isAlive = false;
1347
- }
1348
- }
1349
- // if we found a good value
1350
- thisDevice[rfKeys[rf]] = fieldValue;
1351
- }
1352
- }
1353
-
1354
- // if there is a filter - check the device is in the list
1355
- if (filterName && filterName.length > 0) {
1356
- let found = false;
1357
- for (let f = 0; f < filterName.length; f += 1) {
1358
- if (thisDevice.name.indexOf(filterName[f]) >= 0) {
1359
- found = true;
1360
- break;
1361
- }
1362
- }
1363
- // no matching device - clear the device
1364
- if (!found) {
1365
- thisDevice = {};
1366
- }
1367
- }
1368
-
1369
- return callback(thisDevice, null);
1370
- });
1371
- } catch (e) {
1372
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, e);
1373
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1374
- return callback(null, errorObj);
1375
- }
1061
+ return this.requestHandlerInst.getDevice(deviceName, callback);
1376
1062
  }
1377
1063
 
1378
1064
  /**
1379
1065
  * @summary Get Appliance that match the deviceName
1380
1066
  *
1381
- * @function getDevice
1067
+ * @function getDeviceAuth
1382
1068
  * @param {String} deviceName - the deviceName to find (required)
1069
+ * @param {Object} callOptions - Additional options used to make request, including auth headers, AWS service, or datatypes
1383
1070
  *
1384
1071
  * @param {getCallback} callback - a callback function to return the result
1385
1072
  * (appliance) or the error
1386
1073
  */
1387
- getDevice(deviceName, callback) {
1388
- const meth = 'adapterBase-getDevice';
1389
- const origin = `${this.id}-${meth}`;
1074
+ getDeviceAuth(deviceName, callOptions, callback) {
1075
+ const origin = `${this.id}-adapterBase-getDeviceAuth`;
1390
1076
  log.trace(origin);
1391
1077
 
1392
- // make sure we are set up for device broker getDevice
1393
- if (!this.allProps.devicebroker || !this.allProps.devicebroker.getDevice || this.allProps.devicebroker.getDevice.length === 0 || !this.allProps.devicebroker.getDevice[0].path) {
1394
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getDevice.path'], null, null, null);
1395
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1396
- return callback(null, errorObj);
1397
- }
1398
-
1399
- /* HERE IS WHERE YOU VALIDATE DATA */
1400
- if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
1401
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
1402
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1403
- return callback(null, errorObj);
1404
- }
1405
-
1406
- try {
1407
- // need to get the device so we can convert the deviceName to an id
1408
- // !! if we can do a lookup by name the getDevicesFiltered may not be necessary
1409
- const opts = {
1410
- filter: {
1411
- name: deviceName
1412
- }
1413
- };
1414
- return this.getDevicesFiltered(opts, (devs, ferr) => {
1415
- // if we received an error or their is no response on the results return an error
1416
- if (ferr) {
1417
- return callback(null, ferr);
1418
- }
1419
- if (devs.list.length < 1) {
1420
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
1421
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1422
- return callback(null, errorObj);
1423
- }
1424
-
1425
- const callPromises = [];
1426
- for (let i = 0; i < this.allProps.devicebroker.getDevice.length; i += 1) {
1427
- // Perform component calls here.
1428
- callPromises.push(
1429
- new Promise((resolve, reject) => {
1430
- this.iapMakeBrokerCall('getDevice', this.allProps.devicebroker.getDevice[i], [devs.list[0]], null, (callRet, callErr) => {
1431
- // return an error
1432
- if (callErr) {
1433
- reject(callErr);
1434
- } else {
1435
- // return the data
1436
- resolve(callRet);
1437
- }
1438
- });
1439
- })
1440
- );
1441
- }
1442
-
1443
- // return an array of repsonses
1444
- return Promise.all(callPromises).then((results) => {
1445
- let myResult = {};
1446
- results.forEach((result) => {
1447
- myResult = { ...myResult, ...result };
1448
- });
1449
-
1450
- return callback(myResult, null);
1451
- });
1452
- });
1453
- } catch (ex) {
1454
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
1455
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1456
- return callback(null, errorObj);
1457
- }
1078
+ return this.requestHandlerInst.getDeviceAuth(deviceName, callOptions, callback);
1458
1079
  }
1459
1080
 
1460
1081
  /**
@@ -1467,89 +1088,27 @@ class AdapterBase extends EventEmitterCl {
1467
1088
  * (appliances) or the error
1468
1089
  */
1469
1090
  getDevicesFiltered(options, callback) {
1470
- const meth = 'adapterBase-getDevicesFiltered';
1471
- const origin = `${this.id}-${meth}`;
1091
+ const origin = `${this.id}-adapterBase-getDevicesFiltered`;
1472
1092
  log.trace(origin);
1473
1093
 
1474
- // make sure we are set up for device broker getDevicesFiltered
1475
- if (!this.allProps.devicebroker || !this.allProps.devicebroker.getDevicesFiltered || this.allProps.devicebroker.getDevicesFiltered.length === 0 || !this.allProps.devicebroker.getDevicesFiltered[0].path) {
1476
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getDevicesFiltered.path'], null, null, null);
1477
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1478
- return callback(null, errorObj);
1479
- }
1480
-
1481
- // verify the required fields have been provided
1482
- if (options === undefined || options === null || options === '' || options.length === 0) {
1483
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['options'], null, null, null);
1484
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1485
- return callback(null, errorObj);
1486
- }
1487
- log.debug(`Device Filter Options: ${JSON.stringify(options)}`);
1488
-
1489
- try {
1490
- // TODO - get pagination working
1491
- // const nextToken = options.start;
1492
- // const maxResults = options.limit;
1493
-
1494
- // set up the filter of Device Names
1495
- let filterName = [];
1496
- if (options && options.filter && options.filter.name) {
1497
- // when this hack is removed, remove the lint ignore above
1498
- if (Array.isArray(options.filter.name)) {
1499
- // eslint-disable-next-line prefer-destructuring
1500
- filterName = options.filter.name;
1501
- } else {
1502
- filterName = [options.filter.name];
1503
- }
1504
- }
1505
-
1506
- // TODO - get sort and order working
1507
- /*
1508
- if (options && options.sort) {
1509
- reqObj.uriOptions.sort = JSON.stringify(options.sort);
1510
- }
1511
- if (options && options.order) {
1512
- reqObj.uriOptions.order = options.order;
1513
- }
1514
- */
1515
- const callPromises = [];
1516
- for (let i = 0; i < this.allProps.devicebroker.getDevicesFiltered.length; i += 1) {
1517
- // Perform component calls here.
1518
- callPromises.push(
1519
- new Promise((resolve, reject) => {
1520
- this.iapMakeBrokerCall('getDevicesFiltered', this.allProps.devicebroker.getDevicesFiltered[i], [{ fake: 'fakedata' }], filterName, (callRet, callErr) => {
1521
- // return an error
1522
- if (callErr) {
1523
- reject(callErr);
1524
- } else {
1525
- // return the data
1526
- resolve(callRet);
1527
- }
1528
- });
1529
- })
1530
- );
1531
- }
1094
+ return this.requestHandlerInst.getDevicesFiltered(options, callback);
1095
+ }
1532
1096
 
1533
- // return an array of repsonses
1534
- return Promise.all(callPromises).then((results) => {
1535
- let myResult = [];
1536
- results.forEach((result) => {
1537
- if (Array.isArray(result)) {
1538
- myResult = [...myResult, ...result];
1539
- } else if (Object.keys(result).length > 0) {
1540
- myResult.push(result);
1541
- }
1542
- });
1097
+ /**
1098
+ * @summary Get Appliances that match the filter
1099
+ *
1100
+ * @function getDevicesFilteredAuth
1101
+ * @param {Object} options - the data to use to filter the appliances (optional)
1102
+ * @param {Object} callOptions - Additional options used to make request, including auth headers, AWS service, or datatypes
1103
+ *
1104
+ * @param {getCallback} callback - a callback function to return the result
1105
+ * (appliances) or the error
1106
+ */
1107
+ getDevicesFilteredAuth(options, callOptions, callback) {
1108
+ const origin = `${this.id}-adapterBase-getDevicesFilteredAuth`;
1109
+ log.trace(origin);
1543
1110
 
1544
- log.debug(`${origin}: Found #${myResult.length} devices.`);
1545
- log.debug(`Devices: ${JSON.stringify(myResult)}`);
1546
- return callback({ total: myResult.length, list: myResult });
1547
- });
1548
- } catch (ex) {
1549
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
1550
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1551
- return callback(null, errorObj);
1552
- }
1111
+ return this.requestHandlerInst.getDevicesFilteredAuth(options, callOptions, callback);
1553
1112
  }
1554
1113
 
1555
1114
  /**
@@ -1562,80 +1121,27 @@ class AdapterBase extends EventEmitterCl {
1562
1121
  * (appliance isAlive) or the error
1563
1122
  */
1564
1123
  isAlive(deviceName, callback) {
1565
- const meth = 'adapterBase-isAlive';
1566
- const origin = `${this.id}-${meth}`;
1124
+ const origin = `${this.id}-adapterBase-isAlive`;
1567
1125
  log.trace(origin);
1568
1126
 
1569
- // make sure we are set up for device broker isAlive
1570
- if (!this.allProps.devicebroker || !this.allProps.devicebroker.isAlive || this.allProps.devicebroker.isAlive.length === 0 || !this.allProps.devicebroker.isAlive[0].path) {
1571
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.isAlive.path'], null, null, null);
1572
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1573
- return callback(null, errorObj);
1574
- }
1575
-
1576
- // verify the required fields have been provided
1577
- if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
1578
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
1579
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1580
- return callback(null, errorObj);
1581
- }
1582
-
1583
- try {
1584
- // need to get the device so we can convert the deviceName to an id
1585
- // !! if we can do a lookup by name the getDevicesFiltered may not be necessary
1586
- const opts = {
1587
- filter: {
1588
- name: deviceName
1589
- }
1590
- };
1591
- return this.getDevicesFiltered(opts, (devs, ferr) => {
1592
- // if we received an error or their is no response on the results return an error
1593
- if (ferr) {
1594
- return callback(null, ferr);
1595
- }
1596
- if (devs.list.length < 1) {
1597
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
1598
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1599
- return callback(null, errorObj);
1600
- }
1601
-
1602
- const callPromises = [];
1603
- for (let i = 0; i < this.allProps.devicebroker.isAlive.length; i += 1) {
1604
- // Perform component calls here.
1605
- callPromises.push(
1606
- new Promise((resolve, reject) => {
1607
- this.iapMakeBrokerCall('isAlive', this.allProps.devicebroker.isAlive[i], [devs.list[0]], null, (callRet, callErr) => {
1608
- // return an error
1609
- if (callErr) {
1610
- reject(callErr);
1611
- } else {
1612
- // return the data
1613
- resolve(callRet);
1614
- }
1615
- });
1616
- })
1617
- );
1618
- }
1127
+ return this.requestHandlerInst.isAlive(deviceName, callback);
1128
+ }
1619
1129
 
1620
- // return an array of repsonses
1621
- return Promise.all(callPromises).then((results) => {
1622
- let myResult = {};
1623
- results.forEach((result) => {
1624
- myResult = { ...myResult, ...result };
1625
- });
1130
+ /**
1131
+ * @summary Gets the status for the provided appliance
1132
+ *
1133
+ * @function isAliveAuth
1134
+ * @param {String} deviceName - the deviceName of the appliance. (required)
1135
+ * @param {Object} callOptions - Additional options used to make request, including auth headers, AWS service, or datatypes
1136
+ *
1137
+ * @param {configCallback} callback - callback function to return the result
1138
+ * (appliance isAliveAuth) or the error
1139
+ */
1140
+ isAliveAuth(deviceName, callOptions, callback) {
1141
+ const origin = `${this.id}-adapterBase-isAliveAuth`;
1142
+ log.trace(origin);
1626
1143
 
1627
- let response = true;
1628
- if (myResult.isAlive !== null && myResult.isAlive !== undefined && myResult.isAlive === false) {
1629
- response = false;
1630
- }
1631
- return callback(response);
1632
- });
1633
- });
1634
- } catch (ex) {
1635
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
1636
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1637
- return callback(null, errorObj);
1638
- }
1144
+ return this.requestHandlerInst.isAliveAuth(deviceName, callOptions, callback);
1639
1145
  }
1640
1146
 
1641
1147
  /**
@@ -1649,80 +1155,28 @@ class AdapterBase extends EventEmitterCl {
1649
1155
  * (appliance config) or the error
1650
1156
  */
1651
1157
  getConfig(deviceName, format, callback) {
1652
- const meth = 'adapterBase-getConfig';
1653
- const origin = `${this.id}-${meth}`;
1158
+ const origin = `${this.id}-adapterBase-getConfig`;
1654
1159
  log.trace(origin);
1655
1160
 
1656
- // make sure we are set up for device broker getConfig
1657
- if (!this.allProps.devicebroker || !this.allProps.devicebroker.getConfig || this.allProps.devicebroker.getConfig.length === 0 || !this.allProps.devicebroker.getConfig[0].path) {
1658
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getConfig.path'], null, null, null);
1659
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1660
- return callback(null, errorObj);
1661
- }
1662
-
1663
- // verify the required fields have been provided
1664
- if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
1665
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
1666
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1667
- return callback(null, errorObj);
1668
- }
1669
-
1670
- try {
1671
- // need to get the device so we can convert the deviceName to an id
1672
- // !! if we can do a lookup by name the getDevicesFiltered may not be necessary
1673
- const opts = {
1674
- filter: {
1675
- name: deviceName
1676
- }
1677
- };
1678
- return this.getDevicesFiltered(opts, (devs, ferr) => {
1679
- // if we received an error or their is no response on the results return an error
1680
- if (ferr) {
1681
- return callback(null, ferr);
1682
- }
1683
- if (devs.list.length < 1) {
1684
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
1685
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1686
- return callback(null, errorObj);
1687
- }
1161
+ return this.requestHandlerInst.getConfig(deviceName, format, callback);
1162
+ }
1688
1163
 
1689
- const callPromises = [];
1690
- for (let i = 0; i < this.allProps.devicebroker.getConfig.length; i += 1) {
1691
- // Perform component calls here.
1692
- callPromises.push(
1693
- new Promise((resolve, reject) => {
1694
- this.iapMakeBrokerCall('getConfig', this.allProps.devicebroker.getConfig[i], [devs.list[0]], null, (callRet, callErr) => {
1695
- // return an error
1696
- if (callErr) {
1697
- reject(callErr);
1698
- } else {
1699
- // return the data
1700
- resolve(callRet);
1701
- }
1702
- });
1703
- })
1704
- );
1705
- }
1164
+ /**
1165
+ * @summary Gets a config for the provided Appliance
1166
+ *
1167
+ * @function getConfigAuth
1168
+ * @param {String} deviceName - the deviceName of the appliance. (required)
1169
+ * @param {String} format - the desired format of the config. (optional)
1170
+ * @param {Object} callOptions - Additional options used to make request, including auth headers, AWS service, or datatypes
1171
+ *
1172
+ * @param {configCallback} callback - callback function to return the result
1173
+ * (appliance config) or the error
1174
+ */
1175
+ getConfigAuth(deviceName, format, callOptions, callback) {
1176
+ const origin = `${this.id}-adapterBase-getConfigAuth`;
1177
+ log.trace(origin);
1706
1178
 
1707
- // return an array of repsonses
1708
- return Promise.all(callPromises).then((results) => {
1709
- let myResult = {};
1710
- results.forEach((result) => {
1711
- myResult = { ...myResult, ...result };
1712
- });
1713
-
1714
- // return the result
1715
- const newResponse = {
1716
- response: JSON.stringify(myResult, null, 2)
1717
- };
1718
- return callback(newResponse, null);
1719
- });
1720
- });
1721
- } catch (ex) {
1722
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
1723
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1724
- return callback(null, errorObj);
1725
- }
1179
+ return this.requestHandlerInst.getConfigAuth(deviceName, format, callOptions, callback);
1726
1180
  }
1727
1181
 
1728
1182
  /**
@@ -1734,47 +1188,258 @@ class AdapterBase extends EventEmitterCl {
1734
1188
  * (count) or the error
1735
1189
  */
1736
1190
  iapGetDeviceCount(callback) {
1737
- const meth = 'adapterBase-iapGetDeviceCount';
1191
+ const origin = `${this.id}-adapterBase-iapGetDeviceCount`;
1192
+ log.trace(origin);
1193
+
1194
+ return this.requestHandlerInst.iapGetDeviceCount(callback);
1195
+ }
1196
+
1197
+ /**
1198
+ * @summary Gets the device count from the system
1199
+ *
1200
+ * @function iapGetDeviceCountAuth
1201
+ * @param {Object} callOptions - Additional options used to make request, including auth headers, AWS service, or datatypes
1202
+ *
1203
+ * @param {getCallback} callback - callback function to return the result
1204
+ * (count) or the error
1205
+ */
1206
+ iapGetDeviceCountAuth(callOptions, callback) {
1207
+ const origin = `${this.id}-adapterBase-iapGetDeviceCountAuth`;
1208
+ log.trace(origin);
1209
+
1210
+ return this.requestHandlerInst.iapGetDeviceCountAuth(callOptions, callback);
1211
+ }
1212
+
1213
+ /* ********************************************** */
1214
+ /* */
1215
+ /* EXPOSES GENERIC HANDLER */
1216
+ /* */
1217
+ /* ********************************************** */
1218
+ /**
1219
+ * Makes the requested generic call
1220
+ *
1221
+ * @function iapExpandedGenericAdapterRequest
1222
+ * @param {Object} metadata - metadata for the call (optional).
1223
+ * Can be a stringified Object.
1224
+ * @param {String} uriPath - the path of the api call - do not include the host, port, base path or version (optional)
1225
+ * @param {String} restMethod - the rest method (GET, POST, PUT, PATCH, DELETE) (optional)
1226
+ * @param {Object} pathVars - the parameters to be put within the url path (optional).
1227
+ * Can be a stringified Object.
1228
+ * @param {Object} queryData - the parameters to be put on the url (optional).
1229
+ * Can be a stringified Object.
1230
+ * @param {Object} requestBody - the body to add to the request (optional).
1231
+ * Can be a stringified Object.
1232
+ * @param {Object} addlHeaders - additional headers to be put on the call (optional).
1233
+ * Can be a stringified Object.
1234
+ * @param {getCallback} callback - a callback function to return the result (Generics)
1235
+ * or the error
1236
+ */
1237
+ iapExpandedGenericAdapterRequest(metadata, uriPath, restMethod, pathVars, queryData, requestBody, addlHeaders, callback) {
1238
+ const origin = `${this.myid}-adapterBase-iapExpandedGenericAdapterRequest`;
1239
+ log.trace(origin);
1240
+
1241
+ return this.requestHandlerInst.expandedGenericAdapterRequest(metadata, uriPath, restMethod, pathVars, queryData, requestBody, addlHeaders, callback);
1242
+ }
1243
+
1244
+ /**
1245
+ * Makes the requested generic call
1246
+ *
1247
+ * @function genericAdapterRequest
1248
+ * @param {String} uriPath - the path of the api call - do not include the host, port, base path or version (required)
1249
+ * @param {String} restMethod - the rest method (GET, POST, PUT, PATCH, DELETE) (required)
1250
+ * @param {Object} queryData - the parameters to be put on the url (optional).
1251
+ * Can be a stringified Object.
1252
+ * @param {Object} requestBody - the body to add to the request (optional).
1253
+ * Can be a stringified Object.
1254
+ * @param {Object} addlHeaders - additional headers to be put on the call (optional).
1255
+ * Can be a stringified Object.
1256
+ * @param {getCallback} callback - a callback function to return the result (Generics)
1257
+ * or the error
1258
+ */
1259
+ genericAdapterRequest(uriPath, restMethod, queryData, requestBody, addlHeaders, callback) {
1260
+ const origin = `${this.myid}-adapterBase-genericAdapterRequest`;
1261
+ log.trace(origin);
1262
+
1263
+ return this.requestHandlerInst.genericAdapterRequest(uriPath, restMethod, queryData, requestBody, addlHeaders, callback);
1264
+ }
1265
+
1266
+ /**
1267
+ * Makes the requested generic call with no base path or version
1268
+ *
1269
+ * @function genericAdapterRequestNoBasePath
1270
+ * @param {String} uriPath - the path of the api call - do not include the host, port, base path or version (required)
1271
+ * @param {String} restMethod - the rest method (GET, POST, PUT, PATCH, DELETE) (required)
1272
+ * @param {Object} queryData - the parameters to be put on the url (optional).
1273
+ * Can be a stringified Object.
1274
+ * @param {Object} requestBody - the body to add to the request (optional).
1275
+ * Can be a stringified Object.
1276
+ * @param {Object} addlHeaders - additional headers to be put on the call (optional).
1277
+ * Can be a stringified Object.
1278
+ * @param {getCallback} callback - a callback function to return the result (Generics)
1279
+ * or the error
1280
+ */
1281
+ genericAdapterRequestNoBasePath(uriPath, restMethod, queryData, requestBody, addlHeaders, callback) {
1282
+ const origin = `${this.myid}-adapterBase-genericAdapterRequestNoBasePath`;
1283
+ log.trace(origin);
1284
+
1285
+ return this.requestHandlerInst.genericAdapterRequestNoBasePath(uriPath, restMethod, queryData, requestBody, addlHeaders, callback);
1286
+ }
1287
+
1288
+ /* ********************************************** */
1289
+ /* */
1290
+ /* EXPOSES INVENTORY CALLS */
1291
+ /* */
1292
+ /* ********************************************** */
1293
+ /**
1294
+ * @summary run the adapter lint script to return the results.
1295
+ *
1296
+ * @function iapRunAdapterLint
1297
+ *
1298
+ * @return {Object} - containing the results of the lint call.
1299
+ */
1300
+ iapRunAdapterLint(callback) {
1301
+ const meth = 'adapterBase-iapRunAdapterLint';
1738
1302
  const origin = `${this.id}-${meth}`;
1739
1303
  log.trace(origin);
1304
+ let command = null;
1740
1305
 
1741
- // make sure we are set up for device broker getCount
1742
- if (!this.allProps.devicebroker || !this.allProps.devicebroker.getCount || this.allProps.devicebroker.getCount.length === 0 || !this.allProps.devicebroker.getCount[0].path) {
1743
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getCount.path'], null, null, null);
1744
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1745
- return callback(null, errorObj);
1306
+ if (fs.existsSync('package.json')) {
1307
+ const packageData = require('./package.json');
1308
+
1309
+ // check if 'test', 'test:unit', 'test:integration' exists in package.json file
1310
+ if (!packageData.scripts || !packageData.scripts['lint:errors']) {
1311
+ log.error('The required script does not exist in the package.json file');
1312
+ return callback(null, 'The required script does not exist in the package.json file');
1313
+ }
1314
+
1315
+ // execute 'npm run lint:errors' command
1316
+ command = spawnSync('npm', ['run', 'lint:errors'], { cwd: __dirname, encoding: 'utf-8' });
1317
+
1318
+ // analyze and format the response
1319
+ const result = {
1320
+ status: 'SUCCESS'
1321
+ };
1322
+ if (command.status !== 0) {
1323
+ result.status = 'FAILED';
1324
+ result.output = command.stdout;
1325
+ }
1326
+ return callback(result);
1746
1327
  }
1747
1328
 
1748
- // verify the required fields have been provided
1329
+ log.error('Package Not Found');
1330
+ return callback(null, 'Package Not Found');
1331
+ }
1749
1332
 
1750
- try {
1751
- const callPromises = [];
1752
- for (let i = 0; i < this.allProps.devicebroker.getCount.length; i += 1) {
1753
- // Perform component calls here.
1754
- callPromises.push(
1755
- new Promise((resolve, reject) => {
1756
- this.iapMakeBrokerCall('getCount', this.allProps.devicebroker.getCount[i], null, null, (callRet, callErr) => {
1757
- // return an error
1758
- if (callErr) {
1759
- reject(callErr);
1760
- } else {
1761
- // return the data
1762
- resolve(callRet);
1763
- }
1764
- });
1765
- })
1766
- );
1333
+ /**
1334
+ * @summary run the adapter test scripts (baseunit and unit) to return the results.
1335
+ * can not run integration as there can be implications with that.
1336
+ *
1337
+ * @function iapRunAdapterTests
1338
+ *
1339
+ * @return {Object} - containing the results of the baseunit and unit tests.
1340
+ */
1341
+ iapRunAdapterTests(callback) {
1342
+ const meth = 'adapterBase-iapRunAdapterTests';
1343
+ const origin = `${this.id}-${meth}`;
1344
+ log.trace(origin);
1345
+ let basecommand = null;
1346
+ let command = null;
1347
+
1348
+ if (fs.existsSync('package.json')) {
1349
+ const packageData = require('./package.json');
1350
+
1351
+ // check if 'test', 'test:unit', 'test:integration' exists in package.json file
1352
+ if (!packageData.scripts || !packageData.scripts['test:baseunit'] || !packageData.scripts['test:unit']) {
1353
+ log.error('The required scripts do not exist in the package.json file');
1354
+ return callback(null, 'The required scripts do not exist in the package.json file');
1767
1355
  }
1768
1356
 
1769
- // return an array of repsonses
1770
- return Promise.all(callPromises).then((results) => {
1771
- let myResult = {};
1772
- results.forEach((result) => {
1773
- myResult = { ...myResult, ...result };
1774
- });
1357
+ // run baseunit test
1358
+ basecommand = spawnSync('npm', ['run', 'test:baseunit'], { cwd: __dirname, encoding: 'utf-8' });
1775
1359
 
1776
- // return the result
1777
- return callback({ count: myResult.length });
1360
+ // analyze and format the response to baseunit
1361
+ const baseresult = {
1362
+ status: 'SUCCESS'
1363
+ };
1364
+ if (basecommand.status !== 0) {
1365
+ baseresult.status = 'FAILED';
1366
+ baseresult.output = basecommand.stdout;
1367
+ }
1368
+
1369
+ // run unit test
1370
+ command = spawnSync('npm', ['run', 'test:unit'], { cwd: __dirname, encoding: 'utf-8' });
1371
+
1372
+ // analyze and format the response to unit
1373
+ const unitresult = {
1374
+ status: 'SUCCESS'
1375
+ };
1376
+ if (command.status !== 0) {
1377
+ unitresult.status = 'FAILED';
1378
+ unitresult.output = command.stdout;
1379
+ }
1380
+
1381
+ // format the response and return it
1382
+ const result = {
1383
+ base: baseresult,
1384
+ unit: unitresult
1385
+ };
1386
+ return callback(result);
1387
+ }
1388
+
1389
+ log.error('Package Not Found');
1390
+ return callback(null, 'Package Not Found');
1391
+ }
1392
+
1393
+ /**
1394
+ * @summary provide inventory information abbout the adapter
1395
+ *
1396
+ * @function iapGetAdapterInventory
1397
+ *
1398
+ * @return {Object} - containing the adapter inventory information
1399
+ */
1400
+ iapGetAdapterInventory(callback) {
1401
+ const meth = 'adapterBase-iapGetAdapterInventory';
1402
+ const origin = `${this.id}-${meth}`;
1403
+ log.trace(origin);
1404
+
1405
+ try {
1406
+ // call to the adapter utils to get inventory
1407
+ return this.requestHandlerInst.getAdapterInventory((res, error) => {
1408
+ const adapterInv = res;
1409
+
1410
+ // get all of the tasks
1411
+ const allTasks = this.getAllFunctions();
1412
+ adapterInv.totalTasks = allTasks.length;
1413
+
1414
+ // get all of the possible workflow tasks
1415
+ const myIgnore = [
1416
+ 'healthCheck',
1417
+ 'iapGetAdapterWorkflowFunctions',
1418
+ 'hasEntities'
1419
+ ];
1420
+ adapterInv.totalWorkflowTasks = this.iapGetAdapterWorkflowFunctions(myIgnore).length;
1421
+
1422
+ // TODO: CACHE
1423
+ // CONFIRM CACHE
1424
+ // GET CACHE ENTITIES
1425
+
1426
+ // get the Device Count
1427
+ return this.iapGetDeviceCount((devres, deverror) => {
1428
+ // if call failed assume not broker integrated
1429
+ if (deverror) {
1430
+ adapterInv.brokerDefined = false;
1431
+ adapterInv.deviceCount = -1;
1432
+ } else {
1433
+ // broker confirmed
1434
+ adapterInv.brokerDefined = true;
1435
+ adapterInv.deviceCount = 0;
1436
+ if (devres && devres.count) {
1437
+ adapterInv.deviceCount = devres.count;
1438
+ }
1439
+ }
1440
+
1441
+ return callback(adapterInv);
1442
+ });
1778
1443
  });
1779
1444
  } catch (ex) {
1780
1445
  const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);