@itentialopensource/adapter-microsoft_graph 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. package/.eslintignore +0 -1
  2. package/.jshintrc +3 -0
  3. package/AUTH.md +20 -16
  4. package/CALLS.md +63 -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 +159 -330
  12. package/adapterBase.js +538 -873
  13. package/changelogs/changelog.md +6 -0
  14. package/metadata.json +52 -0
  15. package/package.json +22 -25
  16. package/pronghorn.json +475 -143
  17. package/propertiesSchema.json +444 -40
  18. package/refs?service=git-upload-pack +0 -0
  19. package/report/adapter-openapi.json +14709 -0
  20. package/report/adapter-openapi.yaml +9744 -0
  21. package/report/adapterInfo.json +8 -8
  22. package/report/updateReport1691507370664.json +120 -0
  23. package/report/updateReport1692202407231.json +120 -0
  24. package/report/updateReport1694460353234.json +120 -0
  25. package/report/updateReport1695667793473.json +120 -0
  26. package/sampleProperties.json +66 -3
  27. package/test/integration/adapterTestBasicGet.js +1 -1
  28. package/test/integration/adapterTestConnectivity.js +91 -42
  29. package/test/integration/adapterTestIntegration.js +130 -2
  30. package/test/unit/adapterBaseTestUnit.js +395 -292
  31. package/test/unit/adapterTestUnit.js +306 -109
  32. package/utils/adapterInfo.js +1 -1
  33. package/utils/addAuth.js +1 -1
  34. package/utils/artifactize.js +1 -1
  35. package/utils/checkMigrate.js +1 -1
  36. package/utils/entitiesToDB.js +1 -0
  37. package/utils/findPath.js +1 -1
  38. package/utils/methodDocumentor.js +57 -22
  39. package/utils/modify.js +13 -15
  40. package/utils/packModificationScript.js +1 -1
  41. package/utils/taskMover.js +309 -0
  42. package/utils/tbScript.js +3 -10
  43. package/utils/tbUtils.js +2 -3
  44. package/utils/testRunner.js +1 -1
  45. package/utils/troubleshootingAdapter.js +1 -3
  46. 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);