@itentialopensource/adapter-azure_devops 0.1.11 → 0.2.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 (46) hide show
  1. package/AUTH.md +11 -13
  2. package/CALLS.md +797 -22
  3. package/CHANGELOG.md +16 -0
  4. package/CONTRIBUTING.md +1 -160
  5. package/ENHANCE.md +2 -2
  6. package/README.md +32 -23
  7. package/SYSTEMINFO.md +13 -5
  8. package/adapter.js +162 -333
  9. package/adapterBase.js +549 -879
  10. package/changelogs/CHANGELOG.md +88 -0
  11. package/metadata.json +73 -0
  12. package/package.json +24 -25
  13. package/pronghorn.json +980 -641
  14. package/propertiesSchema.json +431 -31
  15. package/refs?service=git-upload-pack +0 -0
  16. package/report/adapter-openapi.json +29422 -0
  17. package/report/adapter-openapi.yaml +10963 -0
  18. package/report/adapterInfo.json +8 -8
  19. package/report/updateReport1691507719192.json +120 -0
  20. package/report/updateReport1692202716318.json +120 -0
  21. package/report/updateReport1694455416503.json +120 -0
  22. package/report/updateReport1694457083247.json +120 -0
  23. package/report/updateReport1694462876098.json +120 -0
  24. package/report/updateReport1698421291981.json +120 -0
  25. package/sampleProperties.json +63 -2
  26. package/test/integration/adapterTestBasicGet.js +2 -4
  27. package/test/integration/adapterTestConnectivity.js +91 -42
  28. package/test/integration/adapterTestIntegration.js +130 -2
  29. package/test/unit/adapterBaseTestUnit.js +388 -313
  30. package/test/unit/adapterTestUnit.js +338 -112
  31. package/utils/adapterInfo.js +1 -1
  32. package/utils/addAuth.js +1 -1
  33. package/utils/artifactize.js +1 -1
  34. package/utils/checkMigrate.js +1 -1
  35. package/utils/entitiesToDB.js +2 -2
  36. package/utils/findPath.js +1 -1
  37. package/utils/methodDocumentor.js +273 -0
  38. package/utils/modify.js +13 -15
  39. package/utils/packModificationScript.js +1 -1
  40. package/utils/pre-commit.sh +2 -0
  41. package/utils/taskMover.js +309 -0
  42. package/utils/tbScript.js +89 -34
  43. package/utils/tbUtils.js +41 -21
  44. package/utils/testRunner.js +1 -1
  45. package/utils/troubleshootingAdapter.js +9 -6
  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
 
@@ -379,9 +368,15 @@ class AdapterBase extends EventEmitterCl {
379
368
  this.emit('OFFLINE', { id: this.id });
380
369
  this.emit('DEGRADED', { id: this.id });
381
370
  this.healthy = false;
382
- log.error(`${origin}: HEALTH CHECK - Error ${error}`);
383
- } else {
371
+ if (typeof error === 'object') {
372
+ log.error(`${origin}: HEALTH CHECK - Error ${JSON.stringify(error)}`);
373
+ } else {
374
+ log.error(`${origin}: HEALTH CHECK - Error ${error}`);
375
+ }
376
+ } else if (typeof error === 'object') {
384
377
  // still log but set the level to trace
378
+ log.trace(`${origin}: HEALTH CHECK - Still Errors ${JSON.stringify(error)}`);
379
+ } else {
385
380
  log.trace(`${origin}: HEALTH CHECK - Still Errors ${error}`);
386
381
  }
387
382
 
@@ -427,6 +422,40 @@ class AdapterBase extends EventEmitterCl {
427
422
  return myfunctions;
428
423
  }
429
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
+
430
459
  /**
431
460
  * checkActionFiles is used to update the validation of the action files.
432
461
  *
@@ -482,40 +511,6 @@ class AdapterBase extends EventEmitterCl {
482
511
  return this.requestHandlerInst.encryptProperty(property, technique, callback);
483
512
  }
484
513
 
485
- /**
486
- * iapGetAdapterWorkflowFunctions is used to get all of the workflow function in the adapter
487
- * @param {array} ignoreThese - additional methods to ignore (optional)
488
- *
489
- * @function iapGetAdapterWorkflowFunctions
490
- */
491
- iapGetAdapterWorkflowFunctions(ignoreThese) {
492
- const myfunctions = this.getAllFunctions();
493
- const wffunctions = [];
494
-
495
- // remove the functions that should not be in a Workflow
496
- for (let m = 0; m < myfunctions.length; m += 1) {
497
- if (myfunctions[m] === 'addEntityCache') {
498
- // got to the second tier (adapterBase)
499
- break;
500
- }
501
- if (!(myfunctions[m].endsWith('Emit') || myfunctions[m].match(/Emit__v[0-9]+/))) {
502
- let found = false;
503
- if (ignoreThese && Array.isArray(ignoreThese)) {
504
- for (let i = 0; i < ignoreThese.length; i += 1) {
505
- if (myfunctions[m].toUpperCase() === ignoreThese[i].toUpperCase()) {
506
- found = true;
507
- }
508
- }
509
- }
510
- if (!found) {
511
- wffunctions.push(myfunctions[m]);
512
- }
513
- }
514
- }
515
-
516
- return wffunctions;
517
- }
518
-
519
514
  /**
520
515
  * iapUpdateAdapterConfiguration is used to update any of the adapter configuration files. This
521
516
  * allows customers to make changes to adapter configuration without having to be on the
@@ -527,16 +522,17 @@ class AdapterBase extends EventEmitterCl {
527
522
  * @param {string} entity - the entity to be changed, if an action, schema or mock data file (optional)
528
523
  * @param {string} type - the type of entity file to change, (action, schema, mock) (optional)
529
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)
530
526
  * @param {Callback} callback - The results of the call
531
527
  */
532
- iapUpdateAdapterConfiguration(configFile, changes, entity, type, action, callback) {
528
+ iapUpdateAdapterConfiguration(configFile, changes, entity, type, action, replace, callback) {
533
529
  const meth = 'adapterBase-iapUpdateAdapterConfiguration';
534
530
  const origin = `${this.id}-${meth}`;
535
531
  log.trace(origin);
536
532
 
537
533
  // verify the parameters are valid
538
534
  if (changes === undefined || changes === null || typeof changes !== 'object'
539
- || Object.keys(changes).length === 0) {
535
+ || Object.keys(changes).length === 0) {
540
536
  const result = {
541
537
  response: 'No configuration updates to make'
542
538
  };
@@ -621,8 +617,14 @@ class AdapterBase extends EventEmitterCl {
621
617
  if (!fs.existsSync(mpath)) {
622
618
  fs.mkdirSync(mpath);
623
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);
624
627
 
625
- const mres = updateMock(mpath, configFile, changes);
626
628
  if (mres) {
627
629
  const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Incomplete Configuration Change: ${mres}`, [], null, null, null);
628
630
  log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
@@ -639,6 +641,86 @@ class AdapterBase extends EventEmitterCl {
639
641
  return callback(null, errorObj);
640
642
  }
641
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
+ /* ********************************************** */
642
724
  /**
643
725
  * See if the API path provided is found in this adapter
644
726
  *
@@ -659,6 +741,10 @@ class AdapterBase extends EventEmitterCl {
659
741
  return callback(null, result);
660
742
  }
661
743
 
744
+ if (typeof this.allProps.choosepath === 'string') {
745
+ choosepath = this.allProps.choosepath;
746
+ }
747
+
662
748
  // make sure the entities directory exists
663
749
  const entitydir = path.join(__dirname, 'entities');
664
750
  if (!fs.statSync(entitydir).isDirectory()) {
@@ -683,7 +769,25 @@ class AdapterBase extends EventEmitterCl {
683
769
 
684
770
  // go through all of the actions set the appropriate info in the newActions
685
771
  for (let a = 0; a < actions.actions.length; a += 1) {
686
- 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) {
687
791
  log.info(` Found - entity: ${entities[e]} action: ${actions.actions[a].name}`);
688
792
  log.info(` method: ${actions.actions[a].method} path: ${actions.actions[a].entitypath}`);
689
793
  const fitem = {
@@ -722,81 +826,6 @@ class AdapterBase extends EventEmitterCl {
722
826
  return callback(result, null);
723
827
  }
724
828
 
725
- /**
726
- * @summary Suspends the adapter
727
- * @param {Callback} callback - The adapater suspension status
728
- * @function iapSuspendAdapter
729
- */
730
- iapSuspendAdapter(mode, callback) {
731
- const origin = `${this.id}-adapterBase-iapSuspendAdapter`;
732
- if (this.suspended) {
733
- throw new Error(`${origin}: Adapter is already suspended`);
734
- }
735
- try {
736
- this.suspended = true;
737
- this.suspendMode = mode;
738
- if (this.suspendMode === 'pause') {
739
- const props = JSON.parse(JSON.stringify(this.initProps));
740
- // To suspend adapter, enable throttling and set concurrent max to 0
741
- props.throttle.throttle_enabled = true;
742
- props.throttle.concurrent_max = 0;
743
- this.refreshProperties(props);
744
- }
745
- return callback({ suspended: true });
746
- } catch (error) {
747
- return callback(null, error);
748
- }
749
- }
750
-
751
- /**
752
- * @summary Unsuspends the adapter
753
- * @param {Callback} callback - The adapater suspension status
754
- *
755
- * @function iapUnsuspendAdapter
756
- */
757
- iapUnsuspendAdapter(callback) {
758
- const origin = `${this.id}-adapterBase-iapUnsuspendAdapter`;
759
- if (!this.suspended) {
760
- throw new Error(`${origin}: Adapter is not suspended`);
761
- }
762
- if (this.suspendMode === 'pause') {
763
- const props = JSON.parse(JSON.stringify(this.initProps));
764
- // To unsuspend adapter, keep throttling enabled and begin processing queued requests in order
765
- props.throttle.throttle_enabled = true;
766
- props.throttle.concurrent_max = 1;
767
- this.refreshProperties(props);
768
- setTimeout(() => {
769
- this.getQueue((q, error) => {
770
- // console.log("Items in queue: " + String(q.length))
771
- if (q.length === 0) {
772
- // if queue is empty, return to initial properties state
773
- this.refreshProperties(this.initProps);
774
- this.suspended = false;
775
- return callback({ suspended: false });
776
- }
777
- // recursive call to check queue again every second
778
- return this.iapUnsuspendAdapter(callback);
779
- });
780
- }, 1000);
781
- } else {
782
- this.suspended = false;
783
- callback({ suspend: false });
784
- }
785
- }
786
-
787
- /**
788
- * iapGetAdapterQueue is used to get information for all of the requests currently in the queue.
789
- *
790
- * @function iapGetAdapterQueue
791
- * @param {Callback} callback - a callback function to return the result (Queue) or the error
792
- */
793
- iapGetAdapterQueue(callback) {
794
- const origin = `${this.id}-adapterBase-iapGetAdapterQueue`;
795
- log.trace(origin);
796
-
797
- return this.requestHandlerInst.getQueue(callback);
798
- }
799
-
800
829
  /**
801
830
  * @summary runs troubleshoot scripts for adapter
802
831
  *
@@ -831,7 +860,7 @@ class AdapterBase extends EventEmitterCl {
831
860
  if (result) {
832
861
  return callback(result);
833
862
  }
834
- return callback(null, result);
863
+ return callback(null, 'Healthcheck failed');
835
864
  } catch (error) {
836
865
  return callback(null, error);
837
866
  }
@@ -846,8 +875,7 @@ class AdapterBase extends EventEmitterCl {
846
875
  */
847
876
  async iapRunAdapterConnectivity(callback) {
848
877
  try {
849
- const { serviceItem } = await tbUtils.getAdapterConfig();
850
- const { host } = serviceItem.properties.properties;
878
+ const { host } = this.allProps;
851
879
  const result = tbUtils.runConnectivity(host, false);
852
880
  if (result.failCount > 0) {
853
881
  return callback(null, result);
@@ -899,156 +927,89 @@ class AdapterBase extends EventEmitterCl {
899
927
  }
900
928
 
901
929
  /**
902
- * @summary take the entities and add them to the cache
903
- *
904
- * @function addEntityCache
905
- * @param {String} entityType - the type of the entities
906
- * @param {Array} data - the list of entities
907
- * @param {String} key - unique key for the entities
930
+ * @function iapDeactivateTasks
908
931
  *
909
- * @param {Callback} callback - An array of whether the adapter can has the
910
- * desired capability or an error
932
+ * @param {Array} tasks - List of tasks to deactivate
933
+ * @param {Callback} callback
911
934
  */
912
- addEntityCache(entityType, entities, key, callback) {
913
- const meth = 'adapterBase-addEntityCache';
935
+ iapDeactivateTasks(tasks, callback) {
936
+ const meth = 'adapterBase-iapDeactivateTasks';
914
937
  const origin = `${this.id}-${meth}`;
915
938
  log.trace(origin);
916
-
917
- // list containing the items to add to the cache
918
- const entityIds = [];
919
-
920
- if (entities && Object.hasOwnProperty.call(entities, 'response')
921
- && Array.isArray(entities.response)) {
922
- for (let e = 0; e < entities.response.length; e += 1) {
923
- entityIds.push(entities.response[e][key]);
924
- }
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);
925
946
  }
926
-
927
- // add the entities to the cache
928
- return this.requestHandlerInst.addEntityCache(entityType, entityIds, (loaded, error) => {
929
- if (error) {
930
- return callback(null, error);
931
- }
932
- if (!loaded) {
933
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Entity Cache Not Loading', [entityType], null, null, null);
934
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
935
- return callback(null, errorObj);
936
- }
937
-
938
- return callback(loaded);
939
- });
940
- }
947
+ taskMover.deleteBackups(__dirname);
948
+ return callback(data, null);
949
+ }
941
950
 
942
951
  /**
943
- * @summary sees if the entity is in the entity list or not
944
- *
945
- * @function entityInList
946
- * @param {String/Array} entityId - the specific entity we are looking for
947
- * @param {Array} data - the list of entities
952
+ * @function iapActivateTasks
948
953
  *
949
- * @param {Callback} callback - An array of whether the adapter can has the
950
- * desired capability or an error
954
+ * @param {Array} tasks - List of tasks to deactivate
955
+ * @param {Callback} callback
951
956
  */
952
- entityInList(entityId, data) {
953
- const origin = `${this.id}-adapterBase-entityInList`;
957
+ iapActivateTasks(tasks, callback) {
958
+ const meth = 'adapterBase-iapActivateTasks';
959
+ const origin = `${this.id}-${meth}`;
954
960
  log.trace(origin);
955
-
956
- // need to check on the entities that were passed in
957
- if (Array.isArray(entityId)) {
958
- const resEntity = [];
959
-
960
- for (let e = 0; e < entityId.length; e += 1) {
961
- if (data.includes(entityId[e])) {
962
- resEntity.push(true);
963
- } else {
964
- resEntity.push(false);
965
- }
966
- }
967
-
968
- 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);
969
968
  }
970
-
971
- // does the entity list include the specific entity
972
- return [data.includes(entityId)];
969
+ taskMover.deleteBackups(__dirname);
970
+ return callback(data, null);
973
971
  }
974
972
 
973
+ /* ********************************************** */
974
+ /* */
975
+ /* EXPOSES CACHE CALLS */
976
+ /* */
977
+ /* ********************************************** */
975
978
  /**
976
- * @summary prepare results for verify capability so they are true/false
977
- *
978
- * @function capabilityResults
979
- * @param {Array} results - the results from the capability check
979
+ * @summary Populate the cache for the given entities
980
980
  *
981
- * @param {Callback} callback - An array of whether the adapter can has the
982
- * 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
983
985
  */
984
- capabilityResults(results, callback) {
985
- const meth = 'adapterBase-capabilityResults';
986
- const origin = `${this.id}-${meth}`;
986
+ iapPopulateEntityCache(entityTypes, callback) {
987
+ const origin = `${this.myid}-adapterBase-iapPopulateEntityCache`;
987
988
  log.trace(origin);
988
- let locResults = results;
989
-
990
- if (locResults && locResults[0] === 'needupdate') {
991
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Entity Cache Not Loading', ['unknown'], null, null, null);
992
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
993
- this.repeatCacheCount += 1;
994
- return callback(null, errorObj);
995
- }
996
-
997
- // if an error occured, return the error
998
- if (locResults && locResults[0] === 'error') {
999
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Error Verifying Entity Cache', null, null, null, null);
1000
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1001
- return callback(null, errorObj);
1002
- }
1003
-
1004
- // go through the response and change to true/false
1005
- if (locResults) {
1006
- // if not an array, just convert the return
1007
- if (!Array.isArray(locResults)) {
1008
- if (locResults === 'found') {
1009
- locResults = [true];
1010
- } else {
1011
- locResults = [false];
1012
- }
1013
- } else {
1014
- const temp = [];
1015
-
1016
- // go through each element in the array to convert
1017
- for (let r = 0; r < locResults.length; r += 1) {
1018
- if (locResults[r] === 'found') {
1019
- temp.push(true);
1020
- } else {
1021
- temp.push(false);
1022
- }
1023
- }
1024
- locResults = temp;
1025
- }
1026
- }
1027
989
 
1028
- // return the results
1029
- return callback(locResults);
990
+ return this.requestHandlerInst.populateEntityCache(entityTypes, callback);
1030
991
  }
1031
992
 
1032
993
  /**
1033
- * @summary Provides a way for the adapter to tell north bound integrations
1034
- * all of the capabilities for the current adapter
1035
- *
1036
- * @function getAllCapabilities
994
+ * @summary Retrieves data from cache for specified entity type
1037
995
  *
1038
- * @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
1039
1000
  */
1040
- getAllCapabilities() {
1041
- const origin = `${this.id}-adapterBase-getAllCapabilities`;
1001
+ iapRetrieveEntitiesCache(entityType, options, callback) {
1002
+ const origin = `${this.myid}-adapterBase-iapRetrieveEntitiesCache`;
1042
1003
  log.trace(origin);
1043
1004
 
1044
- // validate the capabilities for the adapter
1045
- try {
1046
- return this.requestHandlerInst.getAllCapabilities();
1047
- } catch (e) {
1048
- return [];
1049
- }
1005
+ return this.requestHandlerInst.retrieveEntitiesCache(entityType, options, callback);
1050
1006
  }
1051
1007
 
1008
+ /* ********************************************** */
1009
+ /* */
1010
+ /* EXPOSES BROKER CALLS */
1011
+ /* */
1012
+ /* ********************************************** */
1052
1013
  /**
1053
1014
  * @summary Determines if this adapter supports any in a list of entities
1054
1015
  *
@@ -1060,396 +1021,61 @@ class AdapterBase extends EventEmitterCl {
1060
1021
  * value is true or false
1061
1022
  */
1062
1023
  hasEntities(entityType, entityList, callback) {
1063
- const origin = `${this.id}-adapter-hasEntities`;
1024
+ const origin = `${this.id}-adapterBase-hasEntities`;
1064
1025
  log.trace(origin);
1065
1026
 
1066
- switch (entityType) {
1067
- case 'Device':
1068
- return this.hasDevices(entityList, callback);
1069
- default:
1070
- return callback(null, `${this.id} does not support entity ${entityType}`);
1071
- }
1027
+ return this.requestHandlerInst.hasEntities(entityType, entityList, callback);
1072
1028
  }
1073
1029
 
1074
1030
  /**
1075
- * @summary Helper method for hasEntities for the specific device case
1031
+ * @summary Determines if this adapter supports any in a list of entities
1076
1032
  *
1077
- * @param {Array} deviceList - array of unique device identifiers
1078
- * @param {Callback} callback - A map where the device is the key and the
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
1037
+ *
1038
+ * @param {Callback} callback - A map where the entity is the key and the
1079
1039
  * value is true or false
1080
1040
  */
1081
- hasDevices(deviceList, callback) {
1082
- const origin = `${this.id}-adapter-hasDevices`;
1041
+ hasEntitiesAuth(entityType, entityList, callOptions, callback) {
1042
+ const origin = `${this.id}-adapterBase-hasEntitiesAuth`;
1083
1043
  log.trace(origin);
1084
1044
 
1085
- const findings = deviceList.reduce((map, device) => {
1086
- // eslint-disable-next-line no-param-reassign
1087
- map[device] = false;
1088
- log.debug(`In reduce: ${JSON.stringify(map)}`);
1089
- return map;
1090
- }, {});
1091
- const apiCalls = deviceList.map((device) => new Promise((resolve) => {
1092
- this.getDevice(device, (result, error) => {
1093
- if (error) {
1094
- log.debug(`In map error: ${JSON.stringify(device)}`);
1095
- return resolve({ name: device, found: false });
1096
- }
1097
- log.debug(`In map: ${JSON.stringify(device)}`);
1098
- return resolve({ name: device, found: true });
1099
- });
1100
- }));
1101
- Promise.all(apiCalls).then((results) => {
1102
- results.forEach((device) => {
1103
- findings[device.name] = device.found;
1104
- });
1105
- log.debug(`FINDINGS: ${JSON.stringify(findings)}`);
1106
- return callback(findings);
1107
- }).catch((errors) => {
1108
- log.error('Unable to do device lookup.');
1109
- return callback(null, { code: 503, message: 'Unable to do device lookup.', error: errors });
1110
- });
1045
+ return this.requestHandlerInst.hasEntitiesAuth(entityType, entityList, callOptions, callback);
1111
1046
  }
1112
1047
 
1113
1048
  /**
1114
- * @summary Make one of the needed Broker calls - could be one of many
1049
+ * @summary Get Appliance that match the deviceName
1115
1050
  *
1116
- * @function iapMakeBrokerCall
1117
- * @param {string} brokCall - the name of the broker call (required)
1118
- * @param {object} callProps - the proeprties for the broker call (required)
1119
- * @param {object} devResp - the device details to extract needed inputs (required)
1120
- * @param {string} filterName - any filter to search on (required)
1051
+ * @function getDevice
1052
+ * @param {String} deviceName - the deviceName to find (required)
1121
1053
  *
1122
- * @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
1123
1056
  */
1124
- iapMakeBrokerCall(brokCall, callProps, devResp, filterName, callback) {
1125
- const meth = 'adapterBase-iapMakeBrokerCall';
1126
- const origin = `${this.id}-${meth}`;
1057
+ getDevice(deviceName, callback) {
1058
+ const origin = `${this.id}-adapterBase-getDevice`;
1127
1059
  log.trace(origin);
1128
1060
 
1129
- try {
1130
- let uriPath = '';
1131
- let uriMethod = 'GET';
1132
- let callQuery = {};
1133
- let callBody = {};
1134
- let callHeaders = {};
1135
- let handleFail = 'fail';
1136
- let ostypePrefix = '';
1137
- let statusValue = 'true';
1138
- if (callProps.path) {
1139
- uriPath = `${callProps.path}`;
1140
-
1141
- // make any necessary changes to the path
1142
- if (devResp !== null && callProps.requestFields && Object.keys(callProps.requestFields).length > 0) {
1143
- const rqKeys = Object.keys(callProps.requestFields);
1144
-
1145
- // get the field from the provided device
1146
- for (let rq = 0; rq < rqKeys.length; rq += 1) {
1147
- const fieldValue = getDataFromSources(callProps.requestFields[rqKeys[rq]], devResp);
1148
-
1149
- // put the value into the path - if it has been specified in the path
1150
- uriPath = uriPath.replace(`{${rqKeys[rq]}}`, fieldValue);
1151
- }
1152
- }
1153
- }
1154
- if (callProps.method) {
1155
- uriMethod = callProps.method;
1156
- }
1157
- if (callProps.query) {
1158
- callQuery = callProps.query;
1159
-
1160
- // go through the query params to check for variable values
1161
- const cpKeys = Object.keys(callQuery);
1162
- for (let cp = 0; cp < cpKeys.length; cp += 1) {
1163
- if (callQuery[cpKeys[cp]].startsWith('{') && callQuery[cpKeys[cp]].endsWith('}')) {
1164
- // make any necessary changes to the query params
1165
- if (devResp !== null && callProps.requestFields && Object.keys(callProps.requestFields).length > 0) {
1166
- const rqKeys = Object.keys(callProps.requestFields);
1167
-
1168
- // get the field from the provided device
1169
- for (let rq = 0; rq < rqKeys.length; rq += 1) {
1170
- if (cpKeys[cp] === rqKeys[rq]) {
1171
- const fieldValue = getDataFromSources(callProps.requestFields[rqKeys[rq]], devResp);
1172
-
1173
- // put the value into the query - if it has been specified in the query
1174
- callQuery[cpKeys[cp]] = fieldValue;
1175
- }
1176
- }
1177
- }
1178
- }
1179
- }
1180
- }
1181
- if (callProps.body) {
1182
- callBody = callProps.body;
1183
-
1184
- // go through the body fields to check for variable values
1185
- const cbKeys = Object.keys(callBody);
1186
- for (let cb = 0; cb < cbKeys.length; cb += 1) {
1187
- if (callBody[cbKeys[cb]].startsWith('{') && callBody[cbKeys[cb]].endsWith('}')) {
1188
- // make any necessary changes to the query params
1189
- if (devResp !== null && callProps.requestFields && Object.keys(callProps.requestFields).length > 0) {
1190
- const rqKeys = Object.keys(callProps.requestFields);
1191
-
1192
- // get the field from the provided device
1193
- for (let rq = 0; rq < rqKeys.length; rq += 1) {
1194
- if (cbKeys[cb] === rqKeys[rq]) {
1195
- const fieldValue = getDataFromSources(callProps.requestFields[rqKeys[rq]], devResp);
1196
-
1197
- // put the value into the query - if it has been specified in the query
1198
- callBody[cbKeys[cb]] = fieldValue;
1199
- }
1200
- }
1201
- }
1202
- }
1203
- }
1204
- }
1205
- if (callProps.headers) {
1206
- callHeaders = callProps.headers;
1207
-
1208
- // go through the body fields to check for variable values
1209
- const chKeys = Object.keys(callHeaders);
1210
- for (let ch = 0; ch < chKeys.length; ch += 1) {
1211
- if (callHeaders[chKeys[ch]].startsWith('{') && callHeaders[chKeys[ch]].endsWith('}')) {
1212
- // make any necessary changes to the query params
1213
- if (devResp !== null && callProps.requestFields && Object.keys(callProps.requestFields).length > 0) {
1214
- const rqKeys = Object.keys(callProps.requestFields);
1215
-
1216
- // get the field from the provided device
1217
- for (let rq = 0; rq < rqKeys.length; rq += 1) {
1218
- if (chKeys[ch] === rqKeys[rq]) {
1219
- const fieldValue = getDataFromSources(callProps.requestFields[rqKeys[rq]], devResp);
1220
-
1221
- // put the value into the query - if it has been specified in the query
1222
- callHeaders[chKeys[ch]] = fieldValue;
1223
- }
1224
- }
1225
- }
1226
- }
1227
- }
1228
- }
1229
- if (callProps.handleFailure) {
1230
- handleFail = callProps.handleFailure;
1231
- }
1232
- if (callProps.responseFields && callProps.responseFields.ostypePrefix) {
1233
- ostypePrefix = callProps.responseFields.ostypePrefix;
1234
- }
1235
- if (callProps.responseFields && callProps.responseFields.statusValue) {
1236
- statusValue = callProps.responseFields.statusValue;
1237
- }
1238
-
1239
- // !! using Generic makes it easier on the Adapter Builder (just need to change the path)
1240
- // !! you can also replace with a specific call if that is easier
1241
- return this.genericAdapterRequest(uriPath, uriMethod, callQuery, callBody, callHeaders, (result, error) => {
1242
- // if we received an error or their is no response on the results return an error
1243
- if (error) {
1244
- if (handleFail === 'fail') {
1245
- return callback(null, error);
1246
- }
1247
- return callback({}, null);
1248
- }
1249
- if (!result.response) {
1250
- if (handleFail === 'fail') {
1251
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', [brokCall], null, null, null);
1252
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1253
- return callback(null, errorObj);
1254
- }
1255
- return callback({}, null);
1256
- }
1257
-
1258
- // get the response piece we care about from the response
1259
- const myResult = result;
1260
- if (callProps.responseDatakey) {
1261
- myResult.response = jsonQuery(callProps.responseDatakey, { data: myResult.response }).value;
1262
- }
1263
-
1264
- // get the keys for the response fields
1265
- let rfKeys = [];
1266
- if (callProps.responseFields && Object.keys(callProps.responseFields).length > 0) {
1267
- rfKeys = Object.keys(callProps.responseFields);
1268
- }
1269
-
1270
- // if we got an array returned (e.g. getDevicesFitered)
1271
- if (Array.isArray(myResult.response)) {
1272
- const listDevices = [];
1273
- for (let a = 0; a < myResult.response.length; a += 1) {
1274
- const thisDevice = myResult.response[a];
1275
- for (let rf = 0; rf < rfKeys.length; rf += 1) {
1276
- if (rfKeys[rf] !== 'ostypePrefix') {
1277
- let fieldValue = getDataFromSources(callProps.responseFields[rfKeys[rf]], [thisDevice, devResp, callProps.requestFields]);
1278
-
1279
- // if the field is ostype - need to add prefix
1280
- if (rfKeys[rf] === 'ostype' && typeof fieldValue === 'string') {
1281
- fieldValue = ostypePrefix + fieldValue;
1282
- }
1283
- // if there is a status to set, set it
1284
- if (rfKeys[rf] === 'status') {
1285
- // if really looking for just a good response
1286
- if (callProps.responseFields[rfKeys[rf]] === 'return2xx' && myResult.icode === statusValue.toString()) {
1287
- thisDevice.isAlive = true;
1288
- } else if (fieldValue.toString() === statusValue.toString()) {
1289
- thisDevice.isAlive = true;
1290
- } else {
1291
- thisDevice.isAlive = false;
1292
- }
1293
- }
1294
- // if we found a good value
1295
- thisDevice[rfKeys[rf]] = fieldValue;
1296
- }
1297
- }
1298
-
1299
- // if there is no filter - add the device to the list
1300
- if (!filterName || filterName.length === 0) {
1301
- listDevices.push(thisDevice);
1302
- } else {
1303
- // if we have to match a filter
1304
- let found = false;
1305
- for (let f = 0; f < filterName.length; f += 1) {
1306
- if (thisDevice.name.indexOf(filterName[f]) >= 0) {
1307
- found = true;
1308
- break;
1309
- }
1310
- }
1311
- // matching device
1312
- if (found) {
1313
- listDevices.push(thisDevice);
1314
- }
1315
- }
1316
- }
1317
-
1318
- // return the array of devices
1319
- return callback(listDevices, null);
1320
- }
1321
-
1322
- // if this is not an array - just about everything else, just handle as a single object
1323
- let thisDevice = myResult.response;
1324
- for (let rf = 0; rf < rfKeys.length; rf += 1) {
1325
- // skip ostypePrefix since it is not a field
1326
- if (rfKeys[rf] !== 'ostypePrefix') {
1327
- let fieldValue = getDataFromSources(callProps.responseFields[rfKeys[rf]], [thisDevice, devResp, callProps.requestFields]);
1328
-
1329
- // if the field is ostype - need to add prefix
1330
- if (rfKeys[rf] === 'ostype' && typeof fieldValue === 'string') {
1331
- fieldValue = ostypePrefix + fieldValue;
1332
- }
1333
- // if there is a status to set, set it
1334
- if (rfKeys[rf] === 'status') {
1335
- // if really looking for just a good response
1336
- if (callProps.responseFields[rfKeys[rf]] === 'return2xx' && myResult.icode === statusValue.toString()) {
1337
- thisDevice.isAlive = true;
1338
- } else if (fieldValue.toString() === statusValue.toString()) {
1339
- thisDevice.isAlive = true;
1340
- } else {
1341
- thisDevice.isAlive = false;
1342
- }
1343
- }
1344
- // if we found a good value
1345
- thisDevice[rfKeys[rf]] = fieldValue;
1346
- }
1347
- }
1348
-
1349
- // if there is a filter - check the device is in the list
1350
- if (filterName && filterName.length > 0) {
1351
- let found = false;
1352
- for (let f = 0; f < filterName.length; f += 1) {
1353
- if (thisDevice.name.indexOf(filterName[f]) >= 0) {
1354
- found = true;
1355
- break;
1356
- }
1357
- }
1358
- // no matching device - clear the device
1359
- if (!found) {
1360
- thisDevice = {};
1361
- }
1362
- }
1363
-
1364
- return callback(thisDevice, null);
1365
- });
1366
- } catch (e) {
1367
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, e);
1368
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1369
- return callback(null, errorObj);
1370
- }
1061
+ return this.requestHandlerInst.getDevice(deviceName, callback);
1371
1062
  }
1372
1063
 
1373
1064
  /**
1374
1065
  * @summary Get Appliance that match the deviceName
1375
1066
  *
1376
- * @function getDevice
1067
+ * @function getDeviceAuth
1377
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
1378
1070
  *
1379
1071
  * @param {getCallback} callback - a callback function to return the result
1380
1072
  * (appliance) or the error
1381
1073
  */
1382
- getDevice(deviceName, callback) {
1383
- const meth = 'adapterBase-getDevice';
1384
- const origin = `${this.id}-${meth}`;
1074
+ getDeviceAuth(deviceName, callOptions, callback) {
1075
+ const origin = `${this.id}-adapterBase-getDeviceAuth`;
1385
1076
  log.trace(origin);
1386
1077
 
1387
- // make sure we are set up for device broker getDevice
1388
- if (!this.allProps.devicebroker || !this.allProps.devicebroker.getDevice || this.allProps.devicebroker.getDevice.length === 0 || !this.allProps.devicebroker.getDevice[0].path) {
1389
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getDevice.path'], null, null, null);
1390
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1391
- return callback(null, errorObj);
1392
- }
1393
-
1394
- /* HERE IS WHERE YOU VALIDATE DATA */
1395
- if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
1396
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
1397
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1398
- return callback(null, errorObj);
1399
- }
1400
-
1401
- try {
1402
- // need to get the device so we can convert the deviceName to an id
1403
- // !! if we can do a lookup by name the getDevicesFiltered may not be necessary
1404
- const opts = {
1405
- filter: {
1406
- name: deviceName
1407
- }
1408
- };
1409
- return this.getDevicesFiltered(opts, (devs, ferr) => {
1410
- // if we received an error or their is no response on the results return an error
1411
- if (ferr) {
1412
- return callback(null, ferr);
1413
- }
1414
- if (devs.list.length < 1) {
1415
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
1416
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1417
- return callback(null, errorObj);
1418
- }
1419
-
1420
- const callPromises = [];
1421
- for (let i = 0; i < this.allProps.devicebroker.getDevice.length; i += 1) {
1422
- // Perform component calls here.
1423
- callPromises.push(
1424
- new Promise((resolve, reject) => {
1425
- this.iapMakeBrokerCall('getDevice', this.allProps.devicebroker.getDevice[i], [devs.list[0]], null, (callRet, callErr) => {
1426
- // return an error
1427
- if (callErr) {
1428
- reject(callErr);
1429
- } else {
1430
- // return the data
1431
- resolve(callRet);
1432
- }
1433
- });
1434
- })
1435
- );
1436
- }
1437
-
1438
- // return an array of repsonses
1439
- return Promise.all(callPromises).then((results) => {
1440
- let myResult = {};
1441
- results.forEach((result) => {
1442
- myResult = { ...myResult, ...result };
1443
- });
1444
-
1445
- return callback(myResult, null);
1446
- });
1447
- });
1448
- } catch (ex) {
1449
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
1450
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1451
- return callback(null, errorObj);
1452
- }
1078
+ return this.requestHandlerInst.getDeviceAuth(deviceName, callOptions, callback);
1453
1079
  }
1454
1080
 
1455
1081
  /**
@@ -1462,89 +1088,27 @@ class AdapterBase extends EventEmitterCl {
1462
1088
  * (appliances) or the error
1463
1089
  */
1464
1090
  getDevicesFiltered(options, callback) {
1465
- const meth = 'adapterBase-getDevicesFiltered';
1466
- const origin = `${this.id}-${meth}`;
1091
+ const origin = `${this.id}-adapterBase-getDevicesFiltered`;
1467
1092
  log.trace(origin);
1468
1093
 
1469
- // make sure we are set up for device broker getDevicesFiltered
1470
- if (!this.allProps.devicebroker || !this.allProps.devicebroker.getDevicesFiltered || this.allProps.devicebroker.getDevicesFiltered.length === 0 || !this.allProps.devicebroker.getDevicesFiltered[0].path) {
1471
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getDevicesFiltered.path'], null, null, null);
1472
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1473
- return callback(null, errorObj);
1474
- }
1475
-
1476
- // verify the required fields have been provided
1477
- if (options === undefined || options === null || options === '' || options.length === 0) {
1478
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['options'], null, null, null);
1479
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1480
- return callback(null, errorObj);
1481
- }
1482
- log.debug(`Device Filter Options: ${JSON.stringify(options)}`);
1483
-
1484
- try {
1485
- // TODO - get pagination working
1486
- // const nextToken = options.start;
1487
- // const maxResults = options.limit;
1488
-
1489
- // set up the filter of Device Names
1490
- let filterName = [];
1491
- if (options && options.filter && options.filter.name) {
1492
- // when this hack is removed, remove the lint ignore above
1493
- if (Array.isArray(options.filter.name)) {
1494
- // eslint-disable-next-line prefer-destructuring
1495
- filterName = options.filter.name;
1496
- } else {
1497
- filterName = [options.filter.name];
1498
- }
1499
- }
1500
-
1501
- // TODO - get sort and order working
1502
- /*
1503
- if (options && options.sort) {
1504
- reqObj.uriOptions.sort = JSON.stringify(options.sort);
1505
- }
1506
- if (options && options.order) {
1507
- reqObj.uriOptions.order = options.order;
1508
- }
1509
- */
1510
- const callPromises = [];
1511
- for (let i = 0; i < this.allProps.devicebroker.getDevicesFiltered.length; i += 1) {
1512
- // Perform component calls here.
1513
- callPromises.push(
1514
- new Promise((resolve, reject) => {
1515
- this.iapMakeBrokerCall('getDevicesFiltered', this.allProps.devicebroker.getDevicesFiltered[i], [{ fake: 'fakedata' }], filterName, (callRet, callErr) => {
1516
- // return an error
1517
- if (callErr) {
1518
- reject(callErr);
1519
- } else {
1520
- // return the data
1521
- resolve(callRet);
1522
- }
1523
- });
1524
- })
1525
- );
1526
- }
1094
+ return this.requestHandlerInst.getDevicesFiltered(options, callback);
1095
+ }
1527
1096
 
1528
- // return an array of repsonses
1529
- return Promise.all(callPromises).then((results) => {
1530
- let myResult = [];
1531
- results.forEach((result) => {
1532
- if (Array.isArray(result)) {
1533
- myResult = [...myResult, ...result];
1534
- } else if (Object.keys(result).length > 0) {
1535
- myResult.push(result);
1536
- }
1537
- });
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);
1538
1110
 
1539
- log.debug(`${origin}: Found #${myResult.length} devices.`);
1540
- log.debug(`Devices: ${JSON.stringify(myResult)}`);
1541
- return callback({ total: myResult.length, list: myResult });
1542
- });
1543
- } catch (ex) {
1544
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
1545
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1546
- return callback(null, errorObj);
1547
- }
1111
+ return this.requestHandlerInst.getDevicesFilteredAuth(options, callOptions, callback);
1548
1112
  }
1549
1113
 
1550
1114
  /**
@@ -1557,80 +1121,27 @@ class AdapterBase extends EventEmitterCl {
1557
1121
  * (appliance isAlive) or the error
1558
1122
  */
1559
1123
  isAlive(deviceName, callback) {
1560
- const meth = 'adapterBase-isAlive';
1561
- const origin = `${this.id}-${meth}`;
1124
+ const origin = `${this.id}-adapterBase-isAlive`;
1562
1125
  log.trace(origin);
1563
1126
 
1564
- // make sure we are set up for device broker isAlive
1565
- if (!this.allProps.devicebroker || !this.allProps.devicebroker.isAlive || this.allProps.devicebroker.isAlive.length === 0 || !this.allProps.devicebroker.isAlive[0].path) {
1566
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.isAlive.path'], null, null, null);
1567
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1568
- return callback(null, errorObj);
1569
- }
1570
-
1571
- // verify the required fields have been provided
1572
- if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
1573
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
1574
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1575
- return callback(null, errorObj);
1576
- }
1577
-
1578
- try {
1579
- // need to get the device so we can convert the deviceName to an id
1580
- // !! if we can do a lookup by name the getDevicesFiltered may not be necessary
1581
- const opts = {
1582
- filter: {
1583
- name: deviceName
1584
- }
1585
- };
1586
- return this.getDevicesFiltered(opts, (devs, ferr) => {
1587
- // if we received an error or their is no response on the results return an error
1588
- if (ferr) {
1589
- return callback(null, ferr);
1590
- }
1591
- if (devs.list.length < 1) {
1592
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
1593
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1594
- return callback(null, errorObj);
1595
- }
1596
-
1597
- const callPromises = [];
1598
- for (let i = 0; i < this.allProps.devicebroker.isAlive.length; i += 1) {
1599
- // Perform component calls here.
1600
- callPromises.push(
1601
- new Promise((resolve, reject) => {
1602
- this.iapMakeBrokerCall('isAlive', this.allProps.devicebroker.isAlive[i], [devs.list[0]], null, (callRet, callErr) => {
1603
- // return an error
1604
- if (callErr) {
1605
- reject(callErr);
1606
- } else {
1607
- // return the data
1608
- resolve(callRet);
1609
- }
1610
- });
1611
- })
1612
- );
1613
- }
1127
+ return this.requestHandlerInst.isAlive(deviceName, callback);
1128
+ }
1614
1129
 
1615
- // return an array of repsonses
1616
- return Promise.all(callPromises).then((results) => {
1617
- let myResult = {};
1618
- results.forEach((result) => {
1619
- myResult = { ...myResult, ...result };
1620
- });
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);
1621
1143
 
1622
- let response = true;
1623
- if (myResult.isAlive !== null && myResult.isAlive !== undefined && myResult.isAlive === false) {
1624
- response = false;
1625
- }
1626
- return callback(response);
1627
- });
1628
- });
1629
- } catch (ex) {
1630
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
1631
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1632
- return callback(null, errorObj);
1633
- }
1144
+ return this.requestHandlerInst.isAliveAuth(deviceName, callOptions, callback);
1634
1145
  }
1635
1146
 
1636
1147
  /**
@@ -1644,80 +1155,28 @@ class AdapterBase extends EventEmitterCl {
1644
1155
  * (appliance config) or the error
1645
1156
  */
1646
1157
  getConfig(deviceName, format, callback) {
1647
- const meth = 'adapterBase-getConfig';
1648
- const origin = `${this.id}-${meth}`;
1158
+ const origin = `${this.id}-adapterBase-getConfig`;
1649
1159
  log.trace(origin);
1650
1160
 
1651
- // make sure we are set up for device broker getConfig
1652
- if (!this.allProps.devicebroker || !this.allProps.devicebroker.getConfig || this.allProps.devicebroker.getConfig.length === 0 || !this.allProps.devicebroker.getConfig[0].path) {
1653
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getConfig.path'], null, null, null);
1654
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1655
- return callback(null, errorObj);
1656
- }
1657
-
1658
- // verify the required fields have been provided
1659
- if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
1660
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
1661
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1662
- return callback(null, errorObj);
1663
- }
1664
-
1665
- try {
1666
- // need to get the device so we can convert the deviceName to an id
1667
- // !! if we can do a lookup by name the getDevicesFiltered may not be necessary
1668
- const opts = {
1669
- filter: {
1670
- name: deviceName
1671
- }
1672
- };
1673
- return this.getDevicesFiltered(opts, (devs, ferr) => {
1674
- // if we received an error or their is no response on the results return an error
1675
- if (ferr) {
1676
- return callback(null, ferr);
1677
- }
1678
- if (devs.list.length < 1) {
1679
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
1680
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1681
- return callback(null, errorObj);
1682
- }
1161
+ return this.requestHandlerInst.getConfig(deviceName, format, callback);
1162
+ }
1683
1163
 
1684
- const callPromises = [];
1685
- for (let i = 0; i < this.allProps.devicebroker.getConfig.length; i += 1) {
1686
- // Perform component calls here.
1687
- callPromises.push(
1688
- new Promise((resolve, reject) => {
1689
- this.iapMakeBrokerCall('getConfig', this.allProps.devicebroker.getConfig[i], [devs.list[0]], null, (callRet, callErr) => {
1690
- // return an error
1691
- if (callErr) {
1692
- reject(callErr);
1693
- } else {
1694
- // return the data
1695
- resolve(callRet);
1696
- }
1697
- });
1698
- })
1699
- );
1700
- }
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);
1701
1178
 
1702
- // return an array of repsonses
1703
- return Promise.all(callPromises).then((results) => {
1704
- let myResult = {};
1705
- results.forEach((result) => {
1706
- myResult = { ...myResult, ...result };
1707
- });
1708
-
1709
- // return the result
1710
- const newResponse = {
1711
- response: JSON.stringify(myResult, null, 2)
1712
- };
1713
- return callback(newResponse, null);
1714
- });
1715
- });
1716
- } catch (ex) {
1717
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
1718
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1719
- return callback(null, errorObj);
1720
- }
1179
+ return this.requestHandlerInst.getConfigAuth(deviceName, format, callOptions, callback);
1721
1180
  }
1722
1181
 
1723
1182
  /**
@@ -1729,47 +1188,258 @@ class AdapterBase extends EventEmitterCl {
1729
1188
  * (count) or the error
1730
1189
  */
1731
1190
  iapGetDeviceCount(callback) {
1732
- 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';
1733
1302
  const origin = `${this.id}-${meth}`;
1734
1303
  log.trace(origin);
1304
+ let command = null;
1735
1305
 
1736
- // make sure we are set up for device broker getCount
1737
- if (!this.allProps.devicebroker || !this.allProps.devicebroker.getCount || this.allProps.devicebroker.getCount.length === 0 || !this.allProps.devicebroker.getCount[0].path) {
1738
- const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getCount.path'], null, null, null);
1739
- log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1740
- 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);
1741
1327
  }
1742
1328
 
1743
- // verify the required fields have been provided
1329
+ log.error('Package Not Found');
1330
+ return callback(null, 'Package Not Found');
1331
+ }
1744
1332
 
1745
- try {
1746
- const callPromises = [];
1747
- for (let i = 0; i < this.allProps.devicebroker.getCount.length; i += 1) {
1748
- // Perform component calls here.
1749
- callPromises.push(
1750
- new Promise((resolve, reject) => {
1751
- this.iapMakeBrokerCall('getCount', this.allProps.devicebroker.getCount[i], null, null, (callRet, callErr) => {
1752
- // return an error
1753
- if (callErr) {
1754
- reject(callErr);
1755
- } else {
1756
- // return the data
1757
- resolve(callRet);
1758
- }
1759
- });
1760
- })
1761
- );
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');
1762
1355
  }
1763
1356
 
1764
- // return an array of repsonses
1765
- return Promise.all(callPromises).then((results) => {
1766
- let myResult = {};
1767
- results.forEach((result) => {
1768
- myResult = { ...myResult, ...result };
1769
- });
1357
+ // run baseunit test
1358
+ basecommand = spawnSync('npm', ['run', 'test:baseunit'], { cwd: __dirname, encoding: 'utf-8' });
1770
1359
 
1771
- // return the result
1772
- 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
+ });
1773
1443
  });
1774
1444
  } catch (ex) {
1775
1445
  const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);