@itentialopensource/adapter-meraki 0.8.2 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUTH.md +14 -15
- package/BROKER.md +195 -0
- package/CALLS.md +158 -89
- package/CHANGELOG.md +8 -0
- package/CODE_OF_CONDUCT.md +12 -17
- package/CONTRIBUTING.md +88 -74
- package/ENHANCE.md +14 -14
- package/PROPERTIES.md +483 -89
- package/README.md +131 -51
- package/SUMMARY.md +2 -2
- package/TROUBLESHOOT.md +4 -3
- package/adapter.js +175 -394
- package/adapterBase.js +607 -157
- package/entities/.generic/action.json +105 -0
- package/entities/.generic/schema.json +6 -1
- package/package.json +3 -2
- package/pronghorn.json +79 -0
- package/propertiesSchema.json +13 -0
- package/refs?service=git-upload-pack +0 -0
- package/sampleProperties.json +82 -0
- package/test/unit/adapterBaseTestUnit.js +10 -3
- package/test/unit/adapterTestUnit.js +4 -14
- package/utils/adapterInfo.js +206 -0
- package/utils/pre-commit.sh +3 -0
package/adapterBase.js
CHANGED
@@ -144,6 +144,44 @@ function updatePackage(changes) {
|
|
144
144
|
return null;
|
145
145
|
}
|
146
146
|
|
147
|
+
/*
|
148
|
+
* INTERNAL FUNCTION: get data from source(s) - nested
|
149
|
+
*/
|
150
|
+
function getDataFromSources(loopField, sources) {
|
151
|
+
const loopArray = loopField.split('.');
|
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
|
+
let nestedValue = sources[s];
|
157
|
+
let found = false;
|
158
|
+
|
159
|
+
// loops through incase the field is nested
|
160
|
+
for (let i = 0; i < loopArray.length; i += 1) {
|
161
|
+
// if not nested finds it first pass - otherwise set to new level and loop
|
162
|
+
if (Object.hasOwnProperty.call(nestedValue, loopArray[i])) {
|
163
|
+
nestedValue = nestedValue[loopArray[i]];
|
164
|
+
|
165
|
+
// set found if we are at the leaf (going to stop looping)
|
166
|
+
if (i + 1 === loopArray.length) {
|
167
|
+
found = true;
|
168
|
+
}
|
169
|
+
} else {
|
170
|
+
// not found in source - check next one
|
171
|
+
break;
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
// if we found in source - set and no need to check other sources
|
176
|
+
if (found) {
|
177
|
+
fieldValue = nestedValue;
|
178
|
+
break;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
return fieldValue;
|
183
|
+
}
|
184
|
+
|
147
185
|
/* GENERAL ADAPTER FUNCTIONS THESE SHOULD NOT BE DIRECTLY MODIFIED */
|
148
186
|
/* IF YOU NEED MODIFICATIONS, REDEFINE THEM IN adapter.js!!! */
|
149
187
|
class AdapterBase extends EventEmitterCl {
|
@@ -381,6 +419,85 @@ class AdapterBase extends EventEmitterCl {
|
|
381
419
|
});
|
382
420
|
}
|
383
421
|
|
422
|
+
/**
|
423
|
+
* getAllFunctions is used to get all of the exposed function in the adapter
|
424
|
+
*
|
425
|
+
* @function getAllFunctions
|
426
|
+
*/
|
427
|
+
getAllFunctions() {
|
428
|
+
let myfunctions = [];
|
429
|
+
let obj = this;
|
430
|
+
|
431
|
+
// find the functions in this class
|
432
|
+
do {
|
433
|
+
const l = Object.getOwnPropertyNames(obj)
|
434
|
+
.concat(Object.getOwnPropertySymbols(obj).map((s) => s.toString()))
|
435
|
+
.sort()
|
436
|
+
.filter((p, i, arr) => typeof obj[p] === 'function' && p !== 'constructor' && (i === 0 || p !== arr[i - 1]) && myfunctions.indexOf(p) === -1);
|
437
|
+
myfunctions = myfunctions.concat(l);
|
438
|
+
}
|
439
|
+
while (
|
440
|
+
(obj = Object.getPrototypeOf(obj)) && Object.getPrototypeOf(obj)
|
441
|
+
);
|
442
|
+
|
443
|
+
return myfunctions;
|
444
|
+
}
|
445
|
+
|
446
|
+
/**
|
447
|
+
* checkActionFiles is used to update the validation of the action files.
|
448
|
+
*
|
449
|
+
* @function checkActionFiles
|
450
|
+
*/
|
451
|
+
checkActionFiles() {
|
452
|
+
const origin = `${this.id}-adapterBase-checkActionFiles`;
|
453
|
+
log.trace(origin);
|
454
|
+
|
455
|
+
// validate the action files for the adapter
|
456
|
+
try {
|
457
|
+
return this.requestHandlerInst.checkActionFiles();
|
458
|
+
} catch (e) {
|
459
|
+
return ['Exception increase log level'];
|
460
|
+
}
|
461
|
+
}
|
462
|
+
|
463
|
+
/**
|
464
|
+
* checkProperties is used to validate the adapter properties.
|
465
|
+
*
|
466
|
+
* @function checkProperties
|
467
|
+
* @param {Object} properties - an object containing all of the properties
|
468
|
+
*/
|
469
|
+
checkProperties(properties) {
|
470
|
+
const origin = `${this.myid}-adapterBase-checkProperties`;
|
471
|
+
log.trace(origin);
|
472
|
+
|
473
|
+
// validate the properties for the adapter
|
474
|
+
try {
|
475
|
+
return this.requestHandlerInst.checkProperties(properties);
|
476
|
+
} catch (e) {
|
477
|
+
return { exception: 'Exception increase log level' };
|
478
|
+
}
|
479
|
+
}
|
480
|
+
|
481
|
+
/**
|
482
|
+
* @summary Takes in property text and an encoding/encryption and returns the resulting
|
483
|
+
* encoded/encrypted string
|
484
|
+
*
|
485
|
+
* @function encryptProperty
|
486
|
+
* @param {String} property - the property to encrypt
|
487
|
+
* @param {String} technique - the technique to use to encrypt
|
488
|
+
*
|
489
|
+
* @param {Callback} callback - a callback function to return the result
|
490
|
+
* Encrypted String or the Error
|
491
|
+
*/
|
492
|
+
encryptProperty(property, technique, callback) {
|
493
|
+
const origin = `${this.id}-adapterBase-encryptProperty`;
|
494
|
+
log.trace(origin);
|
495
|
+
|
496
|
+
// Make the call -
|
497
|
+
// encryptProperty(property, technique, callback)
|
498
|
+
return this.requestHandlerInst.encryptProperty(property, technique, callback);
|
499
|
+
}
|
500
|
+
|
384
501
|
/**
|
385
502
|
* iapGetAdapterWorkflowFunctions is used to get all of the workflow function in the adapter
|
386
503
|
* @param {array} ignoreThese - additional methods to ignore (optional)
|
@@ -397,10 +514,7 @@ class AdapterBase extends EventEmitterCl {
|
|
397
514
|
// got to the second tier (adapterBase)
|
398
515
|
break;
|
399
516
|
}
|
400
|
-
if (myfunctions[m]
|
401
|
-
&& myfunctions[m] !== 'iapUpdateAdapterEntityCache' && myfunctions[m] !== 'healthCheck'
|
402
|
-
&& myfunctions[m] !== 'iapGetAdapterWorkflowFunctions'
|
403
|
-
&& !(myfunctions[m].endsWith('Emit') || myfunctions[m].match(/Emit__v[0-9]+/))) {
|
517
|
+
if (!(myfunctions[m].endsWith('Emit') || myfunctions[m].match(/Emit__v[0-9]+/))) {
|
404
518
|
let found = false;
|
405
519
|
if (ignoreThese && Array.isArray(ignoreThese)) {
|
406
520
|
for (let i = 0; i < ignoreThese.length; i += 1) {
|
@@ -799,85 +913,6 @@ class AdapterBase extends EventEmitterCl {
|
|
799
913
|
}
|
800
914
|
}
|
801
915
|
|
802
|
-
/**
|
803
|
-
* getAllFunctions is used to get all of the exposed function in the adapter
|
804
|
-
*
|
805
|
-
* @function getAllFunctions
|
806
|
-
*/
|
807
|
-
getAllFunctions() {
|
808
|
-
let myfunctions = [];
|
809
|
-
let obj = this;
|
810
|
-
|
811
|
-
// find the functions in this class
|
812
|
-
do {
|
813
|
-
const l = Object.getOwnPropertyNames(obj)
|
814
|
-
.concat(Object.getOwnPropertySymbols(obj).map((s) => s.toString()))
|
815
|
-
.sort()
|
816
|
-
.filter((p, i, arr) => typeof obj[p] === 'function' && p !== 'constructor' && (i === 0 || p !== arr[i - 1]) && myfunctions.indexOf(p) === -1);
|
817
|
-
myfunctions = myfunctions.concat(l);
|
818
|
-
}
|
819
|
-
while (
|
820
|
-
(obj = Object.getPrototypeOf(obj)) && Object.getPrototypeOf(obj)
|
821
|
-
);
|
822
|
-
|
823
|
-
return myfunctions;
|
824
|
-
}
|
825
|
-
|
826
|
-
/**
|
827
|
-
* checkActionFiles is used to update the validation of the action files.
|
828
|
-
*
|
829
|
-
* @function checkActionFiles
|
830
|
-
*/
|
831
|
-
checkActionFiles() {
|
832
|
-
const origin = `${this.id}-adapterBase-checkActionFiles`;
|
833
|
-
log.trace(origin);
|
834
|
-
|
835
|
-
// validate the action files for the adapter
|
836
|
-
try {
|
837
|
-
return this.requestHandlerInst.checkActionFiles();
|
838
|
-
} catch (e) {
|
839
|
-
return ['Exception increase log level'];
|
840
|
-
}
|
841
|
-
}
|
842
|
-
|
843
|
-
/**
|
844
|
-
* checkProperties is used to validate the adapter properties.
|
845
|
-
*
|
846
|
-
* @function checkProperties
|
847
|
-
* @param {Object} properties - an object containing all of the properties
|
848
|
-
*/
|
849
|
-
checkProperties(properties) {
|
850
|
-
const origin = `${this.myid}-adapterBase-checkProperties`;
|
851
|
-
log.trace(origin);
|
852
|
-
|
853
|
-
// validate the properties for the adapter
|
854
|
-
try {
|
855
|
-
return this.requestHandlerInst.checkProperties(properties);
|
856
|
-
} catch (e) {
|
857
|
-
return { exception: 'Exception increase log level' };
|
858
|
-
}
|
859
|
-
}
|
860
|
-
|
861
|
-
/**
|
862
|
-
* @summary Takes in property text and an encoding/encryption and returns the resulting
|
863
|
-
* encoded/encrypted string
|
864
|
-
*
|
865
|
-
* @function encryptProperty
|
866
|
-
* @param {String} property - the property to encrypt
|
867
|
-
* @param {String} technique - the technique to use to encrypt
|
868
|
-
*
|
869
|
-
* @param {Callback} callback - a callback function to return the result
|
870
|
-
* Encrypted String or the Error
|
871
|
-
*/
|
872
|
-
encryptProperty(property, technique, callback) {
|
873
|
-
const origin = `${this.id}-adapterBase-encryptProperty`;
|
874
|
-
log.trace(origin);
|
875
|
-
|
876
|
-
// Make the call -
|
877
|
-
// encryptProperty(property, technique, callback)
|
878
|
-
return this.requestHandlerInst.encryptProperty(property, technique, callback);
|
879
|
-
}
|
880
|
-
|
881
916
|
/**
|
882
917
|
* @summary take the entities and add them to the cache
|
883
918
|
*
|
@@ -1029,6 +1064,67 @@ class AdapterBase extends EventEmitterCl {
|
|
1029
1064
|
}
|
1030
1065
|
}
|
1031
1066
|
|
1067
|
+
/**
|
1068
|
+
* @summary Determines if this adapter supports any in a list of entities
|
1069
|
+
*
|
1070
|
+
* @function hasEntities
|
1071
|
+
* @param {String} entityType - the entity type to check for
|
1072
|
+
* @param {Array} entityList - the list of entities we are looking for
|
1073
|
+
*
|
1074
|
+
* @param {Callback} callback - A map where the entity is the key and the
|
1075
|
+
* value is true or false
|
1076
|
+
*/
|
1077
|
+
hasEntities(entityType, entityList, callback) {
|
1078
|
+
const origin = `${this.id}-adapter-hasEntities`;
|
1079
|
+
log.trace(origin);
|
1080
|
+
|
1081
|
+
switch (entityType) {
|
1082
|
+
case 'Device':
|
1083
|
+
return this.hasDevices(entityList, callback);
|
1084
|
+
default:
|
1085
|
+
return callback(null, `${this.id} does not support entity ${entityType}`);
|
1086
|
+
}
|
1087
|
+
}
|
1088
|
+
|
1089
|
+
/**
|
1090
|
+
* @summary Helper method for hasEntities for the specific device case
|
1091
|
+
*
|
1092
|
+
* @param {Array} deviceList - array of unique device identifiers
|
1093
|
+
* @param {Callback} callback - A map where the device is the key and the
|
1094
|
+
* value is true or false
|
1095
|
+
*/
|
1096
|
+
hasDevices(deviceList, callback) {
|
1097
|
+
const origin = `${this.id}-adapter-hasDevices`;
|
1098
|
+
log.trace(origin);
|
1099
|
+
|
1100
|
+
const findings = deviceList.reduce((map, device) => {
|
1101
|
+
// eslint-disable-next-line no-param-reassign
|
1102
|
+
map[device] = false;
|
1103
|
+
log.debug(`In reduce: ${JSON.stringify(map)}`);
|
1104
|
+
return map;
|
1105
|
+
}, {});
|
1106
|
+
const apiCalls = deviceList.map((device) => new Promise((resolve) => {
|
1107
|
+
this.getDevice(device, (result, error) => {
|
1108
|
+
if (error) {
|
1109
|
+
log.debug(`In map error: ${JSON.stringify(device)}`);
|
1110
|
+
return resolve({ name: device, found: false });
|
1111
|
+
}
|
1112
|
+
log.debug(`In map: ${JSON.stringify(device)}`);
|
1113
|
+
return resolve({ name: device, found: true });
|
1114
|
+
});
|
1115
|
+
}));
|
1116
|
+
Promise.all(apiCalls).then((results) => {
|
1117
|
+
results.forEach((device) => {
|
1118
|
+
findings[device.name] = device.found;
|
1119
|
+
});
|
1120
|
+
log.debug(`FINDINGS: ${JSON.stringify(findings)}`);
|
1121
|
+
return callback(findings);
|
1122
|
+
}).catch((errors) => {
|
1123
|
+
log.error('Unable to do device lookup.');
|
1124
|
+
return callback(null, { code: 503, message: 'Unable to do device lookup.', error: errors });
|
1125
|
+
});
|
1126
|
+
}
|
1127
|
+
|
1032
1128
|
/**
|
1033
1129
|
* @summary Make one of the needed Broker calls - could be one of many
|
1034
1130
|
*
|
@@ -1041,7 +1137,7 @@ class AdapterBase extends EventEmitterCl {
|
|
1041
1137
|
* @param {getCallback} callback - a callback function to return the result of the call
|
1042
1138
|
*/
|
1043
1139
|
iapMakeBrokerCall(brokCall, callProps, devResp, filterName, callback) {
|
1044
|
-
const meth = '
|
1140
|
+
const meth = 'adapterBase-iapMakeBrokerCall';
|
1045
1141
|
const origin = `${this.id}-${meth}`;
|
1046
1142
|
log.trace(origin);
|
1047
1143
|
|
@@ -1063,24 +1159,10 @@ class AdapterBase extends EventEmitterCl {
|
|
1063
1159
|
|
1064
1160
|
// get the field from the provided device
|
1065
1161
|
for (let rq = 0; rq < rqKeys.length; rq += 1) {
|
1066
|
-
|
1067
|
-
const loopField = callProps.requestFields[rqKeys[rq]];
|
1068
|
-
const loopArray = loopField.split('.');
|
1069
|
-
let nestedValue = devResp;
|
1070
|
-
|
1071
|
-
// loops through incase the field is nested
|
1072
|
-
for (let i = 0; i < loopArray.length; i += 1) {
|
1073
|
-
if (Object.hasOwnProperty.call(nestedValue, loopArray[i])) {
|
1074
|
-
nestedValue = nestedValue[loopArray[i]];
|
1075
|
-
} else {
|
1076
|
-
// failed to traverse
|
1077
|
-
nestedValue = loopField;
|
1078
|
-
break;
|
1079
|
-
}
|
1080
|
-
}
|
1162
|
+
const fieldValue = getDataFromSources(callProps.requestFields[rqKeys[rq]], devResp);
|
1081
1163
|
|
1082
1164
|
// put the value into the path - if it has been specified in the path
|
1083
|
-
uriPath = uriPath.replace(`{${rqKeys[rq]}}`,
|
1165
|
+
uriPath = uriPath.replace(`{${rqKeys[rq]}}`, fieldValue);
|
1084
1166
|
}
|
1085
1167
|
}
|
1086
1168
|
}
|
@@ -1098,27 +1180,13 @@ class AdapterBase extends EventEmitterCl {
|
|
1098
1180
|
if (devResp !== null && callProps.requestFields && Object.keys(callProps.requestFields).length > 0) {
|
1099
1181
|
const rqKeys = Object.keys(callProps.requestFields);
|
1100
1182
|
|
1101
|
-
// get the
|
1183
|
+
// get the field from the provided device
|
1102
1184
|
for (let rq = 0; rq < rqKeys.length; rq += 1) {
|
1103
1185
|
if (cpKeys[cp] === rqKeys[rq]) {
|
1104
|
-
|
1105
|
-
const loopField = callProps.requestFields[rqKeys[rq]];
|
1106
|
-
const loopArray = loopField.split('.');
|
1107
|
-
let nestedValue = devResp;
|
1108
|
-
|
1109
|
-
// loops through incase the field is nested
|
1110
|
-
for (let i = 0; i < loopArray.length; i += 1) {
|
1111
|
-
if (Object.hasOwnProperty.call(nestedValue, loopArray[i])) {
|
1112
|
-
nestedValue = nestedValue[loopArray[i]];
|
1113
|
-
} else {
|
1114
|
-
// failed to traverse
|
1115
|
-
nestedValue = loopField;
|
1116
|
-
break;
|
1117
|
-
}
|
1118
|
-
}
|
1186
|
+
const fieldValue = getDataFromSources(callProps.requestFields[rqKeys[rq]], devResp);
|
1119
1187
|
|
1120
1188
|
// put the value into the query - if it has been specified in the query
|
1121
|
-
callQuery[cpKeys[cp]] =
|
1189
|
+
callQuery[cpKeys[cp]] = fieldValue;
|
1122
1190
|
}
|
1123
1191
|
}
|
1124
1192
|
}
|
@@ -1173,38 +1241,25 @@ class AdapterBase extends EventEmitterCl {
|
|
1173
1241
|
const thisDevice = result.response[a];
|
1174
1242
|
for (let rf = 0; rf < rfKeys.length; rf += 1) {
|
1175
1243
|
if (rfKeys[rf] !== 'ostypePrefix') {
|
1176
|
-
|
1177
|
-
|
1178
|
-
const loopArray = loopField.split('.');
|
1179
|
-
let nestedValue = thisDevice;
|
1180
|
-
|
1181
|
-
// loops through incase the field is nested
|
1182
|
-
for (let i = 0; i < loopArray.length; i += 1) {
|
1183
|
-
if (Object.hasOwnProperty.call(nestedValue, loopArray[i])) {
|
1184
|
-
nestedValue = nestedValue[loopArray[i]];
|
1185
|
-
} else {
|
1186
|
-
// failed to traverse
|
1187
|
-
nestedValue = '';
|
1188
|
-
break;
|
1189
|
-
}
|
1190
|
-
}
|
1244
|
+
let fieldValue = getDataFromSources(callProps.responseFields[rfKeys[rf]], [thisDevice, devResp, callProps.requestFields]);
|
1245
|
+
|
1191
1246
|
// if the field is ostype - need to add prefix
|
1192
|
-
if (rfKeys[rf] === 'ostype' && typeof
|
1193
|
-
|
1247
|
+
if (rfKeys[rf] === 'ostype' && typeof fieldValue === 'string') {
|
1248
|
+
fieldValue = ostypePrefix + fieldValue;
|
1194
1249
|
}
|
1195
1250
|
// if there is a status to set, set it
|
1196
1251
|
if (rfKeys[rf] === 'status') {
|
1197
1252
|
// if really looking for just a good response
|
1198
|
-
if (
|
1253
|
+
if (callProps.responseFields[rfKeys[rf]] === 'return2xx' && result.icode === statusValue.toString()) {
|
1199
1254
|
thisDevice.isAlive = true;
|
1200
|
-
} else if (
|
1255
|
+
} else if (fieldValue.toString() === statusValue.toString()) {
|
1201
1256
|
thisDevice.isAlive = true;
|
1202
1257
|
} else {
|
1203
1258
|
thisDevice.isAlive = false;
|
1204
1259
|
}
|
1205
1260
|
}
|
1206
1261
|
// if we found a good value
|
1207
|
-
thisDevice[rfKeys[rf]] =
|
1262
|
+
thisDevice[rfKeys[rf]] = fieldValue;
|
1208
1263
|
}
|
1209
1264
|
}
|
1210
1265
|
|
@@ -1236,38 +1291,25 @@ class AdapterBase extends EventEmitterCl {
|
|
1236
1291
|
for (let rf = 0; rf < rfKeys.length; rf += 1) {
|
1237
1292
|
// skip ostypePrefix since it is not a field
|
1238
1293
|
if (rfKeys[rf] !== 'ostypePrefix') {
|
1239
|
-
|
1240
|
-
|
1241
|
-
const loopArray = loopField.split('.');
|
1242
|
-
let nestedValue = thisDevice;
|
1243
|
-
|
1244
|
-
// loops through incase the field is nested
|
1245
|
-
for (let i = 0; i < loopArray.length; i += 1) {
|
1246
|
-
if (Object.hasOwnProperty.call(nestedValue, loopArray[i])) {
|
1247
|
-
nestedValue = nestedValue[loopArray[i]];
|
1248
|
-
} else {
|
1249
|
-
// failed to traverse
|
1250
|
-
nestedValue = '';
|
1251
|
-
break;
|
1252
|
-
}
|
1253
|
-
}
|
1294
|
+
let fieldValue = getDataFromSources(callProps.responseFields[rfKeys[rf]], [thisDevice, devResp, callProps.requestFields]);
|
1295
|
+
|
1254
1296
|
// if the field is ostype - need to add prefix
|
1255
|
-
if (rfKeys[rf] === 'ostype' && typeof
|
1256
|
-
|
1297
|
+
if (rfKeys[rf] === 'ostype' && typeof fieldValue === 'string') {
|
1298
|
+
fieldValue = ostypePrefix + fieldValue;
|
1257
1299
|
}
|
1258
1300
|
// if there is a status to set, set it
|
1259
1301
|
if (rfKeys[rf] === 'status') {
|
1260
1302
|
// if really looking for just a good response
|
1261
|
-
if (
|
1303
|
+
if (callProps.responseFields[rfKeys[rf]] === 'return2xx' && result.icode === statusValue.toString()) {
|
1262
1304
|
thisDevice.isAlive = true;
|
1263
|
-
} else if (
|
1305
|
+
} else if (fieldValue.toString() === statusValue.toString()) {
|
1264
1306
|
thisDevice.isAlive = true;
|
1265
1307
|
} else {
|
1266
1308
|
thisDevice.isAlive = false;
|
1267
1309
|
}
|
1268
1310
|
}
|
1269
1311
|
// if we found a good value
|
1270
|
-
thisDevice[rfKeys[rf]] =
|
1312
|
+
thisDevice[rfKeys[rf]] = fieldValue;
|
1271
1313
|
}
|
1272
1314
|
}
|
1273
1315
|
|
@@ -1294,6 +1336,414 @@ class AdapterBase extends EventEmitterCl {
|
|
1294
1336
|
return callback(null, errorObj);
|
1295
1337
|
}
|
1296
1338
|
}
|
1339
|
+
|
1340
|
+
/**
|
1341
|
+
* @summary Get Appliance that match the deviceName
|
1342
|
+
*
|
1343
|
+
* @function getDevice
|
1344
|
+
* @param {String} deviceName - the deviceName to find (required)
|
1345
|
+
*
|
1346
|
+
* @param {getCallback} callback - a callback function to return the result
|
1347
|
+
* (appliance) or the error
|
1348
|
+
*/
|
1349
|
+
getDevice(deviceName, callback) {
|
1350
|
+
const meth = 'adapterBase-getDevice';
|
1351
|
+
const origin = `${this.id}-${meth}`;
|
1352
|
+
log.trace(origin);
|
1353
|
+
|
1354
|
+
// make sure we are set up for device broker getDevice
|
1355
|
+
if (!this.allProps.devicebroker || !this.allProps.devicebroker.getDevice || this.allProps.devicebroker.getDevice.length === 0 || !this.allProps.devicebroker.getDevice[0].path) {
|
1356
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getDevice.path'], null, null, null);
|
1357
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1358
|
+
return callback(null, errorObj);
|
1359
|
+
}
|
1360
|
+
|
1361
|
+
/* HERE IS WHERE YOU VALIDATE DATA */
|
1362
|
+
if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
|
1363
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
|
1364
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1365
|
+
return callback(null, errorObj);
|
1366
|
+
}
|
1367
|
+
|
1368
|
+
try {
|
1369
|
+
// need to get the device so we can convert the deviceName to an id
|
1370
|
+
// !! if we can do a lookup by name the getDevicesFiltered may not be necessary
|
1371
|
+
const opts = {
|
1372
|
+
filter: {
|
1373
|
+
name: deviceName
|
1374
|
+
}
|
1375
|
+
};
|
1376
|
+
return this.getDevicesFiltered(opts, (devs, ferr) => {
|
1377
|
+
// if we received an error or their is no response on the results return an error
|
1378
|
+
if (ferr) {
|
1379
|
+
return callback(null, ferr);
|
1380
|
+
}
|
1381
|
+
if (devs.list.length < 1) {
|
1382
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
|
1383
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1384
|
+
return callback(null, errorObj);
|
1385
|
+
}
|
1386
|
+
|
1387
|
+
const callPromises = [];
|
1388
|
+
for (let i = 0; i < this.allProps.devicebroker.getDevice.length; i += 1) {
|
1389
|
+
// Perform component calls here.
|
1390
|
+
callPromises.push(
|
1391
|
+
new Promise((resolve, reject) => {
|
1392
|
+
this.iapMakeBrokerCall('getDevice', this.allProps.devicebroker.getDevice[i], [devs.list[0]], null, (callRet, callErr) => {
|
1393
|
+
// return an error
|
1394
|
+
if (callErr) {
|
1395
|
+
reject(callErr);
|
1396
|
+
} else {
|
1397
|
+
// return the data
|
1398
|
+
resolve(callRet);
|
1399
|
+
}
|
1400
|
+
});
|
1401
|
+
})
|
1402
|
+
);
|
1403
|
+
}
|
1404
|
+
|
1405
|
+
// return an array of repsonses
|
1406
|
+
return Promise.all(callPromises).then((results) => {
|
1407
|
+
let myResult = {};
|
1408
|
+
results.forEach((result) => {
|
1409
|
+
myResult = { ...myResult, ...result };
|
1410
|
+
});
|
1411
|
+
|
1412
|
+
return callback(myResult, null);
|
1413
|
+
});
|
1414
|
+
});
|
1415
|
+
} catch (ex) {
|
1416
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
|
1417
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1418
|
+
return callback(null, errorObj);
|
1419
|
+
}
|
1420
|
+
}
|
1421
|
+
|
1422
|
+
/**
|
1423
|
+
* @summary Get Appliances that match the filter
|
1424
|
+
*
|
1425
|
+
* @function getDevicesFiltered
|
1426
|
+
* @param {Object} options - the data to use to filter the appliances (optional)
|
1427
|
+
*
|
1428
|
+
* @param {getCallback} callback - a callback function to return the result
|
1429
|
+
* (appliances) or the error
|
1430
|
+
*/
|
1431
|
+
getDevicesFiltered(options, callback) {
|
1432
|
+
const meth = 'adapterBase-getDevicesFiltered';
|
1433
|
+
const origin = `${this.id}-${meth}`;
|
1434
|
+
log.trace(origin);
|
1435
|
+
|
1436
|
+
// make sure we are set up for device broker getDevicesFiltered
|
1437
|
+
if (!this.allProps.devicebroker || !this.allProps.devicebroker.getDevicesFiltered || this.allProps.devicebroker.getDevicesFiltered.length === 0 || !this.allProps.devicebroker.getDevicesFiltered[0].path) {
|
1438
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getDevicesFiltered.path'], null, null, null);
|
1439
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1440
|
+
return callback(null, errorObj);
|
1441
|
+
}
|
1442
|
+
|
1443
|
+
// verify the required fields have been provided
|
1444
|
+
if (options === undefined || options === null || options === '' || options.length === 0) {
|
1445
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['options'], null, null, null);
|
1446
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1447
|
+
return callback(null, errorObj);
|
1448
|
+
}
|
1449
|
+
log.debug(`Device Filter Options: ${JSON.stringify(options)}`);
|
1450
|
+
|
1451
|
+
try {
|
1452
|
+
// TODO - get pagination working
|
1453
|
+
// const nextToken = options.start;
|
1454
|
+
// const maxResults = options.limit;
|
1455
|
+
|
1456
|
+
// set up the filter of Device Names
|
1457
|
+
let filterName = [];
|
1458
|
+
if (options && options.filter && options.filter.name) {
|
1459
|
+
// when this hack is removed, remove the lint ignore above
|
1460
|
+
if (Array.isArray(options.filter.name)) {
|
1461
|
+
// eslint-disable-next-line prefer-destructuring
|
1462
|
+
filterName = options.filter.name;
|
1463
|
+
} else {
|
1464
|
+
filterName = [options.filter.name];
|
1465
|
+
}
|
1466
|
+
}
|
1467
|
+
|
1468
|
+
// TODO - get sort and order working
|
1469
|
+
/*
|
1470
|
+
if (options && options.sort) {
|
1471
|
+
reqObj.uriOptions.sort = JSON.stringify(options.sort);
|
1472
|
+
}
|
1473
|
+
if (options && options.order) {
|
1474
|
+
reqObj.uriOptions.order = options.order;
|
1475
|
+
}
|
1476
|
+
*/
|
1477
|
+
const callPromises = [];
|
1478
|
+
for (let i = 0; i < this.allProps.devicebroker.getDevicesFiltered.length; i += 1) {
|
1479
|
+
// Perform component calls here.
|
1480
|
+
callPromises.push(
|
1481
|
+
new Promise((resolve, reject) => {
|
1482
|
+
this.iapMakeBrokerCall('getDevicesFiltered', this.allProps.devicebroker.getDevicesFiltered[i], [{ fake: 'fakedata' }], filterName, (callRet, callErr) => {
|
1483
|
+
// return an error
|
1484
|
+
if (callErr) {
|
1485
|
+
reject(callErr);
|
1486
|
+
} else {
|
1487
|
+
// return the data
|
1488
|
+
resolve(callRet);
|
1489
|
+
}
|
1490
|
+
});
|
1491
|
+
})
|
1492
|
+
);
|
1493
|
+
}
|
1494
|
+
|
1495
|
+
// return an array of repsonses
|
1496
|
+
return Promise.all(callPromises).then((results) => {
|
1497
|
+
let myResult = [];
|
1498
|
+
results.forEach((result) => {
|
1499
|
+
if (Array.isArray(result)) {
|
1500
|
+
myResult = [...myResult, ...result];
|
1501
|
+
} else if (Object.keys(result).length > 0) {
|
1502
|
+
myResult.push(result);
|
1503
|
+
}
|
1504
|
+
});
|
1505
|
+
|
1506
|
+
log.debug(`${origin}: Found #${myResult.length} devices.`);
|
1507
|
+
log.debug(`Devices: ${JSON.stringify(myResult)}`);
|
1508
|
+
return callback({ total: myResult.length, list: myResult });
|
1509
|
+
});
|
1510
|
+
} catch (ex) {
|
1511
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
|
1512
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1513
|
+
return callback(null, errorObj);
|
1514
|
+
}
|
1515
|
+
}
|
1516
|
+
|
1517
|
+
/**
|
1518
|
+
* @summary Gets the status for the provided appliance
|
1519
|
+
*
|
1520
|
+
* @function isAlive
|
1521
|
+
* @param {String} deviceName - the deviceName of the appliance. (required)
|
1522
|
+
*
|
1523
|
+
* @param {configCallback} callback - callback function to return the result
|
1524
|
+
* (appliance isAlive) or the error
|
1525
|
+
*/
|
1526
|
+
isAlive(deviceName, callback) {
|
1527
|
+
const meth = 'adapterBase-isAlive';
|
1528
|
+
const origin = `${this.id}-${meth}`;
|
1529
|
+
log.trace(origin);
|
1530
|
+
|
1531
|
+
// make sure we are set up for device broker isAlive
|
1532
|
+
if (!this.allProps.devicebroker || !this.allProps.devicebroker.isAlive || this.allProps.devicebroker.isAlive.length === 0 || !this.allProps.devicebroker.isAlive[0].path) {
|
1533
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.isAlive.path'], null, null, null);
|
1534
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1535
|
+
return callback(null, errorObj);
|
1536
|
+
}
|
1537
|
+
|
1538
|
+
// verify the required fields have been provided
|
1539
|
+
if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
|
1540
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
|
1541
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1542
|
+
return callback(null, errorObj);
|
1543
|
+
}
|
1544
|
+
|
1545
|
+
try {
|
1546
|
+
// need to get the device so we can convert the deviceName to an id
|
1547
|
+
// !! if we can do a lookup by name the getDevicesFiltered may not be necessary
|
1548
|
+
const opts = {
|
1549
|
+
filter: {
|
1550
|
+
name: deviceName
|
1551
|
+
}
|
1552
|
+
};
|
1553
|
+
return this.getDevicesFiltered(opts, (devs, ferr) => {
|
1554
|
+
// if we received an error or their is no response on the results return an error
|
1555
|
+
if (ferr) {
|
1556
|
+
return callback(null, ferr);
|
1557
|
+
}
|
1558
|
+
if (devs.list.length < 1) {
|
1559
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
|
1560
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1561
|
+
return callback(null, errorObj);
|
1562
|
+
}
|
1563
|
+
|
1564
|
+
const callPromises = [];
|
1565
|
+
for (let i = 0; i < this.allProps.devicebroker.isAlive.length; i += 1) {
|
1566
|
+
// Perform component calls here.
|
1567
|
+
callPromises.push(
|
1568
|
+
new Promise((resolve, reject) => {
|
1569
|
+
this.iapMakeBrokerCall('isAlive', this.allProps.devicebroker.isAlive[i], [devs.list[0]], null, (callRet, callErr) => {
|
1570
|
+
// return an error
|
1571
|
+
if (callErr) {
|
1572
|
+
reject(callErr);
|
1573
|
+
} else {
|
1574
|
+
// return the data
|
1575
|
+
resolve(callRet);
|
1576
|
+
}
|
1577
|
+
});
|
1578
|
+
})
|
1579
|
+
);
|
1580
|
+
}
|
1581
|
+
|
1582
|
+
// return an array of repsonses
|
1583
|
+
return Promise.all(callPromises).then((results) => {
|
1584
|
+
let myResult = {};
|
1585
|
+
results.forEach((result) => {
|
1586
|
+
myResult = { ...myResult, ...result };
|
1587
|
+
});
|
1588
|
+
|
1589
|
+
let response = true;
|
1590
|
+
if (myResult.isAlive !== null && myResult.isAlive !== undefined && myResult.isAlive === false) {
|
1591
|
+
response = false;
|
1592
|
+
}
|
1593
|
+
return callback(response);
|
1594
|
+
});
|
1595
|
+
});
|
1596
|
+
} catch (ex) {
|
1597
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
|
1598
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1599
|
+
return callback(null, errorObj);
|
1600
|
+
}
|
1601
|
+
}
|
1602
|
+
|
1603
|
+
/**
|
1604
|
+
* @summary Gets a config for the provided Appliance
|
1605
|
+
*
|
1606
|
+
* @function getConfig
|
1607
|
+
* @param {String} deviceName - the deviceName of the appliance. (required)
|
1608
|
+
* @param {String} format - the desired format of the config. (optional)
|
1609
|
+
*
|
1610
|
+
* @param {configCallback} callback - callback function to return the result
|
1611
|
+
* (appliance config) or the error
|
1612
|
+
*/
|
1613
|
+
getConfig(deviceName, format, callback) {
|
1614
|
+
const meth = 'adapterBase-getConfig';
|
1615
|
+
const origin = `${this.id}-${meth}`;
|
1616
|
+
log.trace(origin);
|
1617
|
+
|
1618
|
+
// make sure we are set up for device broker getConfig
|
1619
|
+
if (!this.allProps.devicebroker || !this.allProps.devicebroker.getConfig || this.allProps.devicebroker.getConfig.length === 0 || !this.allProps.devicebroker.getConfig[0].path) {
|
1620
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getConfig.path'], null, null, null);
|
1621
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1622
|
+
return callback(null, errorObj);
|
1623
|
+
}
|
1624
|
+
|
1625
|
+
// verify the required fields have been provided
|
1626
|
+
if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
|
1627
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
|
1628
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1629
|
+
return callback(null, errorObj);
|
1630
|
+
}
|
1631
|
+
|
1632
|
+
try {
|
1633
|
+
// need to get the device so we can convert the deviceName to an id
|
1634
|
+
// !! if we can do a lookup by name the getDevicesFiltered may not be necessary
|
1635
|
+
const opts = {
|
1636
|
+
filter: {
|
1637
|
+
name: deviceName
|
1638
|
+
}
|
1639
|
+
};
|
1640
|
+
return this.getDevicesFiltered(opts, (devs, ferr) => {
|
1641
|
+
// if we received an error or their is no response on the results return an error
|
1642
|
+
if (ferr) {
|
1643
|
+
return callback(null, ferr);
|
1644
|
+
}
|
1645
|
+
if (devs.list.length < 1) {
|
1646
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
|
1647
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1648
|
+
return callback(null, errorObj);
|
1649
|
+
}
|
1650
|
+
|
1651
|
+
const callPromises = [];
|
1652
|
+
for (let i = 0; i < this.allProps.devicebroker.getConfig.length; i += 1) {
|
1653
|
+
// Perform component calls here.
|
1654
|
+
callPromises.push(
|
1655
|
+
new Promise((resolve, reject) => {
|
1656
|
+
this.iapMakeBrokerCall('getConfig', this.allProps.devicebroker.getConfig[i], [devs.list[0]], null, (callRet, callErr) => {
|
1657
|
+
// return an error
|
1658
|
+
if (callErr) {
|
1659
|
+
reject(callErr);
|
1660
|
+
} else {
|
1661
|
+
// return the data
|
1662
|
+
resolve(callRet);
|
1663
|
+
}
|
1664
|
+
});
|
1665
|
+
})
|
1666
|
+
);
|
1667
|
+
}
|
1668
|
+
|
1669
|
+
// return an array of repsonses
|
1670
|
+
return Promise.all(callPromises).then((results) => {
|
1671
|
+
let myResult = {};
|
1672
|
+
results.forEach((result) => {
|
1673
|
+
myResult = { ...myResult, ...result };
|
1674
|
+
});
|
1675
|
+
|
1676
|
+
// return the result
|
1677
|
+
const newResponse = {
|
1678
|
+
response: JSON.stringify(myResult, null, 2)
|
1679
|
+
};
|
1680
|
+
return callback(newResponse, null);
|
1681
|
+
});
|
1682
|
+
});
|
1683
|
+
} catch (ex) {
|
1684
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
|
1685
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1686
|
+
return callback(null, errorObj);
|
1687
|
+
}
|
1688
|
+
}
|
1689
|
+
|
1690
|
+
/**
|
1691
|
+
* @summary Gets the device count from the system
|
1692
|
+
*
|
1693
|
+
* @function iapGetDeviceCount
|
1694
|
+
*
|
1695
|
+
* @param {getCallback} callback - callback function to return the result
|
1696
|
+
* (count) or the error
|
1697
|
+
*/
|
1698
|
+
iapGetDeviceCount(callback) {
|
1699
|
+
const meth = 'adapterBase-iapGetDeviceCount';
|
1700
|
+
const origin = `${this.id}-${meth}`;
|
1701
|
+
log.trace(origin);
|
1702
|
+
|
1703
|
+
// make sure we are set up for device broker getCount
|
1704
|
+
if (!this.allProps.devicebroker || !this.allProps.devicebroker.getCount || this.allProps.devicebroker.getCount.length === 0 || !this.allProps.devicebroker.getCount[0].path) {
|
1705
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getCount.path'], null, null, null);
|
1706
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1707
|
+
return callback(null, errorObj);
|
1708
|
+
}
|
1709
|
+
|
1710
|
+
// verify the required fields have been provided
|
1711
|
+
|
1712
|
+
try {
|
1713
|
+
const callPromises = [];
|
1714
|
+
for (let i = 0; i < this.allProps.devicebroker.getCount.length; i += 1) {
|
1715
|
+
// Perform component calls here.
|
1716
|
+
callPromises.push(
|
1717
|
+
new Promise((resolve, reject) => {
|
1718
|
+
this.iapMakeBrokerCall('getCount', this.allProps.devicebroker.getCount[i], null, null, (callRet, callErr) => {
|
1719
|
+
// return an error
|
1720
|
+
if (callErr) {
|
1721
|
+
reject(callErr);
|
1722
|
+
} else {
|
1723
|
+
// return the data
|
1724
|
+
resolve(callRet);
|
1725
|
+
}
|
1726
|
+
});
|
1727
|
+
})
|
1728
|
+
);
|
1729
|
+
}
|
1730
|
+
|
1731
|
+
// return an array of repsonses
|
1732
|
+
return Promise.all(callPromises).then((results) => {
|
1733
|
+
let myResult = {};
|
1734
|
+
results.forEach((result) => {
|
1735
|
+
myResult = { ...myResult, ...result };
|
1736
|
+
});
|
1737
|
+
|
1738
|
+
// return the result
|
1739
|
+
return callback({ count: myResult.length });
|
1740
|
+
});
|
1741
|
+
} catch (ex) {
|
1742
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
|
1743
|
+
log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
|
1744
|
+
return callback(null, errorObj);
|
1745
|
+
}
|
1746
|
+
}
|
1297
1747
|
}
|
1298
1748
|
|
1299
1749
|
module.exports = AdapterBase;
|