@itentialopensource/adapter-meraki 0.7.2 → 0.8.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.
package/adapter.js CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  /* eslint import/no-dynamic-require: warn */
4
4
  /* eslint object-curly-newline: warn */
5
- /* eslint no-underscore-dangle: warn */
6
- /* eslint camelcase: warn */
7
5
 
8
6
  // Set globals
9
7
  /* global log */
@@ -82,10 +80,10 @@ class Meraki extends AdapterBaseCl {
82
80
  }
83
81
 
84
82
  /**
85
- * @getWorkflowFunctions
83
+ * @iapGetAdapterWorkflowFunctions
86
84
  */
87
- getWorkflowFunctions(inIgnore) {
88
- let myIgnore = [];
85
+ iapGetAdapterWorkflowFunctions(inIgnore) {
86
+ let myIgnore = ['hasEntities', 'hasDevices'];
89
87
  if (!inIgnore && Array.isArray(inIgnore)) {
90
88
  myIgnore = inIgnore;
91
89
  } else if (!inIgnore && typeof inIgnore === 'string') {
@@ -96,15 +94,15 @@ class Meraki extends AdapterBaseCl {
96
94
  // you can add specific methods that you do not want to be workflow functions to ignore like below
97
95
  // myIgnore.push('myMethodNotInWorkflow');
98
96
 
99
- return super.getWorkflowFunctions(myIgnore);
97
+ return super.iapGetAdapterWorkflowFunctions(myIgnore);
100
98
  }
101
99
 
102
100
  /**
103
- * updateAdapterConfiguration is used to update any of the adapter configuration files. This
101
+ * iapUpdateAdapterConfiguration is used to update any of the adapter configuration files. This
104
102
  * allows customers to make changes to adapter configuration without having to be on the
105
103
  * file system.
106
104
  *
107
- * @function updateAdapterConfiguration
105
+ * @function iapUpdateAdapterConfiguration
108
106
  * @param {string} configFile - the name of the file being updated (required)
109
107
  * @param {Object} changes - an object containing all of the changes = formatted like the configuration file (required)
110
108
  * @param {string} entity - the entity to be changed, if an action, schema or mock data file (optional)
@@ -112,36 +110,36 @@ class Meraki extends AdapterBaseCl {
112
110
  * @param {string} action - the action to be changed, if an action, schema or mock data file (optional)
113
111
  * @param {Callback} callback - The results of the call
114
112
  */
115
- updateAdapterConfiguration(configFile, changes, entity, type, action, callback) {
116
- const origin = `${this.id}-adapter-updateAdapterConfiguration`;
113
+ iapUpdateAdapterConfiguration(configFile, changes, entity, type, action, callback) {
114
+ const origin = `${this.id}-adapter-iapUpdateAdapterConfiguration`;
117
115
  log.trace(origin);
118
- super.updateAdapterConfiguration(configFile, changes, entity, type, action, callback);
116
+ super.iapUpdateAdapterConfiguration(configFile, changes, entity, type, action, callback);
119
117
  }
120
118
 
121
119
  /**
122
120
  * See if the API path provided is found in this adapter
123
121
  *
124
- * @function findPath
122
+ * @function iapFindAdapterPath
125
123
  * @param {string} apiPath - the api path to check on
126
124
  * @param {Callback} callback - The results of the call
127
125
  */
128
- findPath(apiPath, callback) {
129
- const origin = `${this.id}-adapter-findPath`;
126
+ iapFindAdapterPath(apiPath, callback) {
127
+ const origin = `${this.id}-adapter-iapFindAdapterPath`;
130
128
  log.trace(origin);
131
- super.findPath(apiPath, callback);
129
+ super.iapFindAdapterPath(apiPath, callback);
132
130
  }
133
131
 
134
132
  /**
135
133
  * @summary Suspends adapter
136
134
  *
137
- * @function suspend
135
+ * @function iapSuspendAdapter
138
136
  * @param {Callback} callback - callback function
139
137
  */
140
- suspend(mode, callback) {
141
- const origin = `${this.id}-adapter-suspend`;
138
+ iapSuspendAdapter(mode, callback) {
139
+ const origin = `${this.id}-adapter-iapSuspendAdapter`;
142
140
  log.trace(origin);
143
141
  try {
144
- return super.suspend(mode, callback);
142
+ return super.iapSuspendAdapter(mode, callback);
145
143
  } catch (error) {
146
144
  log.error(`${origin}: ${error}`);
147
145
  return callback(null, error);
@@ -151,14 +149,14 @@ class Meraki extends AdapterBaseCl {
151
149
  /**
152
150
  * @summary Unsuspends adapter
153
151
  *
154
- * @function unsuspend
152
+ * @function iapUnsuspendAdapter
155
153
  * @param {Callback} callback - callback function
156
154
  */
157
- unsuspend(callback) {
158
- const origin = `${this.id}-adapter-unsuspend`;
155
+ iapUnsuspendAdapter(callback) {
156
+ const origin = `${this.id}-adapter-iapUnsuspendAdapter`;
159
157
  log.trace(origin);
160
158
  try {
161
- return super.unsuspend(callback);
159
+ return super.iapUnsuspendAdapter(callback);
162
160
  } catch (error) {
163
161
  log.error(`${origin}: ${error}`);
164
162
  return callback(null, error);
@@ -168,29 +166,29 @@ class Meraki extends AdapterBaseCl {
168
166
  /**
169
167
  * @summary Get the Adaoter Queue
170
168
  *
171
- * @function getQueue
169
+ * @function iapGetAdapterQueue
172
170
  * @param {Callback} callback - callback function
173
171
  */
174
- getQueue(callback) {
175
- const origin = `${this.id}-adapter-getQueue`;
172
+ iapGetAdapterQueue(callback) {
173
+ const origin = `${this.id}-adapter-iapGetAdapterQueue`;
176
174
  log.trace(origin);
177
- return super.getQueue(callback);
175
+ return super.iapGetAdapterQueue(callback);
178
176
  }
179
177
 
180
178
  /**
181
179
  * @summary Runs troubleshoot scripts for adapter
182
180
  *
183
- * @function troubleshoot
181
+ * @function iapTroubleshootAdapter
184
182
  * @param {Object} props - the connection, healthcheck and authentication properties
185
183
  *
186
184
  * @param {boolean} persistFlag - whether the adapter properties should be updated
187
185
  * @param {Callback} callback - The results of the call
188
186
  */
189
- troubleshoot(props, persistFlag, callback) {
190
- const origin = `${this.id}-adapter-troubleshoot`;
187
+ iapTroubleshootAdapter(props, persistFlag, callback) {
188
+ const origin = `${this.id}-adapter-iapTroubleshootAdapter`;
191
189
  log.trace(origin);
192
190
  try {
193
- return super.troubleshoot(props, persistFlag, this, callback);
191
+ return super.iapTroubleshootAdapter(props, persistFlag, this, callback);
194
192
  } catch (error) {
195
193
  log.error(`${origin}: ${error}`);
196
194
  return callback(null, error);
@@ -200,15 +198,15 @@ class Meraki extends AdapterBaseCl {
200
198
  /**
201
199
  * @summary runs healthcheck script for adapter
202
200
  *
203
- * @function runHealthcheck
201
+ * @function iapRunAdapterHealthcheck
204
202
  * @param {Adapter} adapter - adapter instance to troubleshoot
205
203
  * @param {Callback} callback - callback function
206
204
  */
207
- runHealthcheck(callback) {
208
- const origin = `${this.id}-adapter-runHealthcheck`;
205
+ iapRunAdapterHealthcheck(callback) {
206
+ const origin = `${this.id}-adapter-iapRunAdapterHealthcheck`;
209
207
  log.trace(origin);
210
208
  try {
211
- return super.runHealthcheck(this, callback);
209
+ return super.iapRunAdapterHealthcheck(this, callback);
212
210
  } catch (error) {
213
211
  log.error(`${origin}: ${error}`);
214
212
  return callback(null, error);
@@ -218,14 +216,14 @@ class Meraki extends AdapterBaseCl {
218
216
  /**
219
217
  * @summary runs connectivity check script for adapter
220
218
  *
221
- * @function runConnectivity
219
+ * @function iapRunAdapterConnectivity
222
220
  * @param {Callback} callback - callback function
223
221
  */
224
- runConnectivity(callback) {
225
- const origin = `${this.id}-adapter-runConnectivity`;
222
+ iapRunAdapterConnectivity(callback) {
223
+ const origin = `${this.id}-adapter-iapRunAdapterConnectivity`;
226
224
  log.trace(origin);
227
225
  try {
228
- return super.runConnectivity(callback);
226
+ return super.iapRunAdapterConnectivity(callback);
229
227
  } catch (error) {
230
228
  log.error(`${origin}: ${error}`);
231
229
  return callback(null, error);
@@ -235,44 +233,63 @@ class Meraki extends AdapterBaseCl {
235
233
  /**
236
234
  * @summary runs basicGet script for adapter
237
235
  *
238
- * @function runBasicGet
236
+ * @function iapRunAdapterBasicGet
239
237
  * @param {Callback} callback - callback function
240
238
  */
241
- runBasicGet(callback) {
242
- const origin = `${this.id}-adapter-runBasicGet`;
239
+ iapRunAdapterBasicGet(callback) {
240
+ const origin = `${this.id}-adapter-iapRunAdapterBasicGet`;
243
241
  log.trace(origin);
244
242
  try {
245
- return super.runBasicGet(callback);
243
+ return super.iapRunAdapterBasicGet(callback);
246
244
  } catch (error) {
247
245
  log.error(`${origin}: ${error}`);
248
246
  return callback(null, error);
249
247
  }
250
248
  }
251
249
 
250
+ /**
251
+ * @summary moves entites into Mongo DB
252
+ *
253
+ * @function iapMoveAdapterEntitiesToDB
254
+ * @param {getCallback} callback - a callback function to return the result (Generics)
255
+ * or the error
256
+ */
257
+ iapMoveAdapterEntitiesToDB(callback) {
258
+ const origin = `${this.id}-adapter-iapMoveAdapterEntitiesToDB`;
259
+ log.trace(origin);
260
+ try {
261
+ return super.iapMoveAdapterEntitiesToDB(callback);
262
+ } catch (err) {
263
+ log.error(`${origin}: ${err}`);
264
+ return callback(null, err);
265
+ }
266
+ }
267
+
268
+ /* BROKER CALLS */
252
269
  /**
253
270
  * @summary Determines if this adapter supports the specific entity
254
271
  *
255
- * @function hasEntity
272
+ * @function iapHasAdapterEntity
256
273
  * @param {String} entityType - the entity type to check for
257
274
  * @param {String/Array} entityId - the specific entity we are looking for
258
275
  *
259
276
  * @param {Callback} callback - An array of whether the adapter can has the
260
277
  * desired capability or an error
261
278
  */
262
- hasEntity(entityType, entityId, callback) {
263
- const origin = `${this.id}-adapter-hasEntity`;
279
+ iapHasAdapterEntity(entityType, entityId, callback) {
280
+ const origin = `${this.id}-adapter-iapHasAdapterEntity`;
264
281
  log.trace(origin);
265
282
 
266
283
  // Make the call -
267
- // verifyCapability(entityType, actionType, entityId, callback)
268
- return this.verifyCapability(entityType, null, entityId, callback);
284
+ // iapVerifyAdapterCapability(entityType, actionType, entityId, callback)
285
+ return this.iapVerifyAdapterCapability(entityType, null, entityId, callback);
269
286
  }
270
287
 
271
288
  /**
272
289
  * @summary Provides a way for the adapter to tell north bound integrations
273
290
  * whether the adapter supports type, action and specific entity
274
291
  *
275
- * @function verifyCapability
292
+ * @function iapVerifyAdapterCapability
276
293
  * @param {String} entityType - the entity type to check for
277
294
  * @param {String} actionType - the action type to check for
278
295
  * @param {String/Array} entityId - the specific entity we are looking for
@@ -280,15 +297,15 @@ class Meraki extends AdapterBaseCl {
280
297
  * @param {Callback} callback - An array of whether the adapter can has the
281
298
  * desired capability or an error
282
299
  */
283
- verifyCapability(entityType, actionType, entityId, callback) {
284
- const meth = 'adapterBase-verifyCapability';
300
+ iapVerifyAdapterCapability(entityType, actionType, entityId, callback) {
301
+ const meth = 'adapterBase-iapVerifyAdapterCapability';
285
302
  const origin = `${this.id}-${meth}`;
286
303
  log.trace(origin);
287
304
 
288
305
  // if caching
289
306
  if (this.caching) {
290
- // Make the call - verifyCapability(entityType, actionType, entityId, callback)
291
- return this.requestHandlerInst.verifyCapability(entityType, actionType, entityId, (results, error) => {
307
+ // Make the call - iapVerifyAdapterCapability(entityType, actionType, entityId, callback)
308
+ return this.requestHandlerInst.iapVerifyAdapterCapability(entityType, actionType, entityId, (results, error) => {
292
309
  if (error) {
293
310
  return callback(null, error);
294
311
  }
@@ -306,7 +323,7 @@ class Meraki extends AdapterBaseCl {
306
323
  }
307
324
 
308
325
  // need to check the cache again since it has been updated
309
- return this.requestHandlerInst.verifyCapability(entityType, actionType, entityId, (vcapable, verror) => {
326
+ return this.requestHandlerInst.iapVerifyAdapterCapability(entityType, actionType, entityId, (vcapable, verror) => {
310
327
  if (verror) {
311
328
  return callback(null, verror);
312
329
  }
@@ -339,7 +356,7 @@ class Meraki extends AdapterBaseCl {
339
356
  // if no entity id
340
357
  if (!entityId) {
341
358
  // need to check the cache again since it has been updated
342
- return this.requestHandlerInst.verifyCapability(entityType, actionType, null, (vcapable, verror) => {
359
+ return this.requestHandlerInst.iapVerifyAdapterCapability(entityType, actionType, null, (vcapable, verror) => {
343
360
  if (verror) {
344
361
  return callback(null, verror);
345
362
  }
@@ -360,7 +377,7 @@ class Meraki extends AdapterBaseCl {
360
377
  }
361
378
 
362
379
  // need to check the cache again since it has been updated
363
- return this.requestHandlerInst.verifyCapability(entityType, actionType, null, (vcapable, verror) => {
380
+ return this.requestHandlerInst.iapVerifyAdapterCapability(entityType, actionType, null, (vcapable, verror) => {
364
381
  if (verror) {
365
382
  return callback(null, verror);
366
383
  }
@@ -401,11 +418,11 @@ class Meraki extends AdapterBaseCl {
401
418
  /**
402
419
  * @summary Updates the cache for all entities by call the get All entity method
403
420
  *
404
- * @function updateEntityCache
421
+ * @function iapUpdateAdapterEntityCache
405
422
  *
406
423
  */
407
- updateEntityCache() {
408
- const origin = `${this.id}-adapter-updateEntityCache`;
424
+ iapUpdateAdapterEntityCache() {
425
+ const origin = `${this.id}-adapter-iapUpdateAdapterEntityCache`;
409
426
  log.trace(origin);
410
427
 
411
428
  if (this.caching) {
@@ -418,6 +435,836 @@ class Meraki extends AdapterBaseCl {
418
435
  }
419
436
  }
420
437
 
438
+ /**
439
+ * @summary Determines if this adapter supports any in a list of entities
440
+ *
441
+ * @function hasEntities
442
+ * @param {String} entityType - the entity type to check for
443
+ * @param {Array} entityList - the list of entities we are looking for
444
+ *
445
+ * @param {Callback} callback - A map where the entity is the key and the
446
+ * value is true or false
447
+ */
448
+ hasEntities(entityType, entityList, callback) {
449
+ const origin = `${this.id}-adapter-hasEntities`;
450
+ log.trace(origin);
451
+
452
+ switch (entityType) {
453
+ case 'Device':
454
+ return this.hasDevices(entityList, callback);
455
+ default:
456
+ return callback(null, `${this.id} does not support entity ${entityType}`);
457
+ }
458
+ }
459
+
460
+ /**
461
+ * @summary Helper method for hasEntities for the specific device case
462
+ *
463
+ * @param {Array} deviceList - array of unique device identifiers
464
+ * @param {Callback} callback - A map where the device is the key and the
465
+ * value is true or false
466
+ */
467
+ hasDevices(deviceList, callback) {
468
+ const origin = `${this.id}-adapter-hasDevices`;
469
+ log.trace(origin);
470
+
471
+ const findings = deviceList.reduce((map, device) => {
472
+ // eslint-disable-next-line no-param-reassign
473
+ map[device] = false;
474
+ log.debug(`In reduce: ${JSON.stringify(map)}`);
475
+ return map;
476
+ }, {});
477
+ const apiCalls = deviceList.map((device) => new Promise((resolve) => {
478
+ this.getDevice(device, (result, error) => {
479
+ if (error) {
480
+ log.debug(`In map error: ${JSON.stringify(device)}`);
481
+ return resolve({ name: device, found: false });
482
+ }
483
+ log.debug(`In map: ${JSON.stringify(device)}`);
484
+ return resolve({ name: device, found: true });
485
+ });
486
+ }));
487
+ Promise.all(apiCalls).then((results) => {
488
+ results.forEach((device) => {
489
+ findings[device.name] = device.found;
490
+ });
491
+ log.debug(`FINDINGS: ${JSON.stringify(findings)}`);
492
+ return callback(findings);
493
+ }).catch((errors) => {
494
+ log.error('Unable to do device lookup.');
495
+ return callback(null, { code: 503, message: 'Unable to do device lookup.', error: errors });
496
+ });
497
+ }
498
+
499
+ /**
500
+ * @summary Get Appliance that match the deviceName
501
+ *
502
+ * @function getDevice
503
+ * @param {String} deviceName - the deviceName to find (required)
504
+ *
505
+ * @param {getCallback} callback - a callback function to return the result
506
+ * (appliance) or the error
507
+ */
508
+ getDevice(deviceName, callback) {
509
+ const meth = 'adapter-getDevice';
510
+ const origin = `${this.id}-${meth}`;
511
+ log.trace(origin);
512
+
513
+ // make sure we are set up for device broker getDevice
514
+ if (!this.props.devicebroker || !this.props.devicebroker.getDevice || !this.props.devicebroker.getDevice.path) {
515
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getDevice.path'], null, null, null);
516
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
517
+ return callback(null, errorObj);
518
+ }
519
+
520
+ /* HERE IS WHERE YOU VALIDATE DATA */
521
+ if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
522
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
523
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
524
+ return callback(null, errorObj);
525
+ }
526
+
527
+ try {
528
+ // need to get the device so we can convert the deviceName to an id
529
+ // !! if we can do a lookup by name the getDevicesFiltered may not be necessary
530
+ const opts = {
531
+ filter: {
532
+ name: deviceName
533
+ }
534
+ };
535
+ return this.getDevicesFiltered(opts, (devs, ferr) => {
536
+ // if we received an error or their is no response on the results return an error
537
+ if (ferr) {
538
+ return callback(null, ferr);
539
+ }
540
+ if (devs.list.length < 1) {
541
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
542
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
543
+ return callback(null, errorObj);
544
+ }
545
+ // get the uuid from the device
546
+ const { uuid } = devs.list[0];
547
+
548
+ // !! using Generic makes it easier on the Adapter Builder (just need to change the path)
549
+ // !! you can also replace with a specific call if that is easier
550
+ let uriPath = '';
551
+ let uriMethod = 'GET';
552
+ let callQuery = {};
553
+ let callBody = {};
554
+ let callHeaders = {};
555
+ let nameField = 'name';
556
+ let nameArray = ['name'];
557
+ let ostypeField = 'ostype';
558
+ let ostypeArray = ['ostype'];
559
+ let ostypePrefix = '';
560
+ let portField = 'port';
561
+ let portArray = ['port'];
562
+ let ipField = 'ipaddress';
563
+ let ipArray = ['ipaddress'];
564
+ if (this.props.devicebroker.getDevice.path) {
565
+ uriPath = `${this.props.devicebroker.getDevice.path}`;
566
+ uriPath = uriPath.replace('{deviceid}', uuid);
567
+ }
568
+ if (this.props.devicebroker.getDevice.method) {
569
+ uriMethod = this.props.devicebroker.getDevice.method;
570
+ }
571
+ if (this.props.devicebroker.getDevice.query) {
572
+ try {
573
+ callQuery = JSON.parse(this.props.devicebroker.getDevice.query);
574
+ } catch (e) {
575
+ log.warn('Could not parse query parameter for getDevice call');
576
+ }
577
+ }
578
+ if (this.props.devicebroker.getDevice.body) {
579
+ try {
580
+ callBody = this.props.devicebroker.getDevice.body;
581
+ } catch (e) {
582
+ log.warn('Could not parse body for getDevice call');
583
+ }
584
+ }
585
+ if (this.props.devicebroker.getDevice.headers) {
586
+ try {
587
+ callHeaders = this.props.devicebroker.getDevice.headers;
588
+ } catch (e) {
589
+ log.warn('Could not parse headers for getDevice call');
590
+ }
591
+ }
592
+ if (this.props.devicebroker.getDevice.name_field) {
593
+ nameField = this.props.devicebroker.getDevice.name_field;
594
+ nameArray = nameField.split('.');
595
+ }
596
+ if (this.props.devicebroker.getDevice.ostype_field) {
597
+ ostypeField = this.props.devicebroker.getDevice.ostype_field;
598
+ ostypeArray = ostypeField.split('.');
599
+ }
600
+ if (this.props.devicebroker.getDevice.ostype_prefix) {
601
+ ostypePrefix = this.props.devicebroker.getDevice.ostype_prefix;
602
+ }
603
+ if (this.props.devicebroker.getDevice.port_field) {
604
+ portField = this.props.devicebroker.getDevice.port_field;
605
+ portArray = portField.split('.');
606
+ }
607
+ if (this.props.devicebroker.getDevice.ip_field) {
608
+ ipField = this.props.devicebroker.getDevice.ip_field;
609
+ ipArray = ipField.split('.');
610
+ }
611
+
612
+ return this.genericAdapterRequest(uriPath, uriMethod, callQuery, callBody, callHeaders, (result, error) => {
613
+ // if we received an error or their is no response on the results return an error
614
+ if (error) {
615
+ return callback(null, error);
616
+ }
617
+ if (!result.response) {
618
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevice'], null, null, null);
619
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
620
+ return callback(null, errorObj);
621
+ }
622
+
623
+ // return the response
624
+ // !! format the data we send back
625
+ // !! these fields are config manager fields you need to map to the data we receive
626
+ const thisDevice = result.response;
627
+ let thisName = thisDevice;
628
+ for (let i = 0; i < nameArray.length; i += 1) {
629
+ if (!Object.hasOwnProperty.call(thisName, nameArray[i])) {
630
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
631
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
632
+ return callback(null, errorObj);
633
+ }
634
+ thisName = thisName[nameArray[i]];
635
+ }
636
+ thisDevice.name = thisName;
637
+ let thisOstype = thisDevice;
638
+ for (let i = 0; i < ostypeArray.length; i += 1) {
639
+ if (!Object.hasOwnProperty.call(thisOstype, ostypeArray[i])) {
640
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
641
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
642
+ return callback(null, errorObj);
643
+ }
644
+ thisOstype = thisOstype[ostypeArray[i]];
645
+ }
646
+ thisDevice.ostype = ostypePrefix + thisOstype;
647
+ let thisPort = thisDevice;
648
+ for (let i = 0; i < portArray.length; i += 1) {
649
+ if (!Object.hasOwnProperty.call(thisPort, portArray[i])) {
650
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
651
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
652
+ return callback(null, errorObj);
653
+ }
654
+ thisPort = thisPort[portArray[i]];
655
+ }
656
+ thisDevice.port = thisPort;
657
+ let thisIp = thisDevice;
658
+ for (let i = 0; i < ipArray.length; i += 1) {
659
+ if (!Object.hasOwnProperty.call(thisIp, ipArray[i])) {
660
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
661
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
662
+ return callback(null, errorObj);
663
+ }
664
+ thisIp = thisIp[ipArray[i]];
665
+ }
666
+ thisDevice.ipaddress = thisIp;
667
+ return callback(thisDevice);
668
+ });
669
+ });
670
+ } catch (ex) {
671
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
672
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
673
+ return callback(null, errorObj);
674
+ }
675
+ }
676
+
677
+ /**
678
+ * @summary Get Appliances that match the filter
679
+ *
680
+ * @function getDevicesFiltered
681
+ * @param {Object} options - the data to use to filter the appliances (optional)
682
+ *
683
+ * @param {getCallback} callback - a callback function to return the result
684
+ * (appliances) or the error
685
+ */
686
+ getDevicesFiltered(options, callback) {
687
+ const meth = 'adapter-getDevicesFiltered';
688
+ const origin = `${this.id}-${meth}`;
689
+ log.trace(origin);
690
+
691
+ // make sure we are set up for device broker getDevicesFiltered
692
+ if (!this.props.devicebroker || !this.props.devicebroker.getDevicesFiltered || !this.props.devicebroker.getDevicesFiltered.path) {
693
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getDevicesFiltered.path'], null, null, null);
694
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
695
+ return callback(null, errorObj);
696
+ }
697
+
698
+ // verify the required fields have been provided
699
+ if (options === undefined || options === null || options === '' || options.length === 0) {
700
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['options'], null, null, null);
701
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
702
+ return callback(null, errorObj);
703
+ }
704
+ log.debug(`Device Filter Options: ${JSON.stringify(options)}`);
705
+
706
+ // TODO - get pagination working
707
+ // const nextToken = options.start;
708
+ // const maxResults = options.limit;
709
+
710
+ // set up the filter of Device Names
711
+ let filterName = [];
712
+ if (options && options.filter && options.filter.name) {
713
+ // when this hack is removed, remove the lint ignore above
714
+ if (Array.isArray(options.filter.name)) {
715
+ // eslint-disable-next-line prefer-destructuring
716
+ filterName = options.filter.name;
717
+ } else {
718
+ filterName = [options.filter.name];
719
+ }
720
+ }
721
+
722
+ // TODO - get sort and order working
723
+ /*
724
+ if (options && options.sort) {
725
+ reqObj.uriOptions.sort = JSON.stringify(options.sort);
726
+ }
727
+ if (options && options.order) {
728
+ reqObj.uriOptions.order = options.order;
729
+ }
730
+ */
731
+ try {
732
+ // !! using Generic makes it easier on the Adapter Builder (just need to change the path)
733
+ // !! you can also replace with a specific call if that is easier
734
+ let uriPath = '';
735
+ let uriMethod = 'GET';
736
+ let callQuery = {};
737
+ let callBody = {};
738
+ let callHeaders = {};
739
+ let nameField = 'name';
740
+ let nameArray = ['name'];
741
+ let ostypeField = 'ostype';
742
+ let ostypeArray = ['ostype'];
743
+ let ostypePrefix = '';
744
+ let portField = 'port';
745
+ let portArray = ['port'];
746
+ let ipField = 'ipaddress';
747
+ let ipArray = ['ipaddress'];
748
+ if (this.props.devicebroker.getDevicesFiltered.path) {
749
+ uriPath = this.props.devicebroker.getDevicesFiltered.path;
750
+ }
751
+ if (this.props.devicebroker.getDevicesFiltered.method) {
752
+ uriMethod = this.props.devicebroker.getDevicesFiltered.method;
753
+ }
754
+ if (this.props.devicebroker.getDevicesFiltered.query) {
755
+ try {
756
+ callQuery = this.props.devicebroker.getDevicesFiltered.query;
757
+ } catch (e) {
758
+ log.warn('Could not parse query parameter for getDevicesFiltered call');
759
+ }
760
+ }
761
+ if (this.props.devicebroker.getDevicesFiltered.body) {
762
+ try {
763
+ callBody = this.props.devicebroker.getDevicesFiltered.body;
764
+ } catch (e) {
765
+ log.warn('Could not parse body for getDevicesFiltered call');
766
+ }
767
+ }
768
+ if (this.props.devicebroker.getDevicesFiltered.headers) {
769
+ try {
770
+ callHeaders = this.props.devicebroker.getDevicesFiltered.headers;
771
+ } catch (e) {
772
+ log.warn('Could not parse headers for getDevicesFiltered call');
773
+ }
774
+ }
775
+ if (this.props.devicebroker.getDevicesFiltered.name_field) {
776
+ nameField = this.props.devicebroker.getDevicesFiltered.name_field;
777
+ nameArray = nameField.split('.');
778
+ }
779
+ if (this.props.devicebroker.getDevicesFiltered.ostype_field) {
780
+ ostypeField = this.props.devicebroker.getDevicesFiltered.ostype_field;
781
+ ostypeArray = ostypeField.split('.');
782
+ }
783
+ if (this.props.devicebroker.getDevicesFiltered.ostype_prefix) {
784
+ ostypePrefix = this.props.devicebroker.getDevicesFiltered.ostype_prefix;
785
+ }
786
+ if (this.props.devicebroker.getDevicesFiltered.port_field) {
787
+ portField = this.props.devicebroker.getDevicesFiltered.port_field;
788
+ portArray = portField.split('.');
789
+ }
790
+ if (this.props.devicebroker.getDevicesFiltered.ip_field) {
791
+ ipField = this.props.devicebroker.getDevicesFiltered.ip_field;
792
+ ipArray = ipField.split('.');
793
+ }
794
+
795
+ return this.genericAdapterRequest(uriPath, uriMethod, callQuery, callBody, callHeaders, (result, error) => {
796
+ // if we received an error or their is no response on the results return an error
797
+ if (error) {
798
+ return callback(null, error);
799
+ }
800
+ if (!result.response) {
801
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
802
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
803
+ return callback(null, errorObj);
804
+ }
805
+
806
+ // !! go through the response - may have to look for sub object
807
+ // handle an array of devices
808
+ if (Array.isArray(result.response)) {
809
+ const myDevices = [];
810
+
811
+ for (let d = 0; d < result.response.length; d += 1) {
812
+ // !! format the data we send back
813
+ // !! these fields are config manager fields you need to map to the data we receive
814
+ const thisDevice = result.response;
815
+ let thisName = thisDevice;
816
+ for (let i = 0; i < nameArray.length; i += 1) {
817
+ if (!Object.hasOwnProperty.call(thisName, nameArray[i])) {
818
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
819
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
820
+ return callback(null, errorObj);
821
+ }
822
+ thisName = thisName[nameArray[i]];
823
+ }
824
+ thisDevice.name = thisName;
825
+ let thisOstype = thisDevice;
826
+ for (let i = 0; i < ostypeArray.length; i += 1) {
827
+ if (!Object.hasOwnProperty.call(thisOstype, ostypeArray[i])) {
828
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
829
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
830
+ return callback(null, errorObj);
831
+ }
832
+ thisOstype = thisOstype[ostypeArray[i]];
833
+ }
834
+ thisDevice.ostype = ostypePrefix + thisOstype;
835
+ let thisPort = thisDevice;
836
+ for (let i = 0; i < portArray.length; i += 1) {
837
+ if (!Object.hasOwnProperty.call(thisPort, portArray[i])) {
838
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
839
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
840
+ return callback(null, errorObj);
841
+ }
842
+ thisPort = thisPort[portArray[i]];
843
+ }
844
+ thisDevice.port = thisPort;
845
+ let thisIp = thisDevice;
846
+ for (let i = 0; i < ipArray.length; i += 1) {
847
+ if (!Object.hasOwnProperty.call(thisIp, ipArray[i])) {
848
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
849
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
850
+ return callback(null, errorObj);
851
+ }
852
+ thisIp = thisIp[ipArray[i]];
853
+ }
854
+ thisDevice.ipaddress = thisIp;
855
+
856
+ // if there is no filter - return the device
857
+ if (filterName.length === 0) {
858
+ myDevices.push(thisDevice);
859
+ } else {
860
+ // if we have to match a filter
861
+ let found = false;
862
+ for (let f = 0; f < filterName.length; f += 1) {
863
+ if (thisDevice.name.indexOf(filterName[f]) >= 0) {
864
+ found = true;
865
+ break;
866
+ }
867
+ }
868
+ // matching device
869
+ if (found) {
870
+ myDevices.push(thisDevice);
871
+ }
872
+ }
873
+ }
874
+ log.debug(`${origin}: Found #${myDevices.length} devices.`);
875
+ log.debug(`Devices: ${JSON.stringify(myDevices)}`);
876
+ return callback({ total: myDevices.length, list: myDevices });
877
+ }
878
+ // handle a single device response
879
+ // !! format the data we send back
880
+ // !! these fields are config manager fields you need to map to the data we receive
881
+ const thisDevice = result.response;
882
+ let thisName = thisDevice;
883
+ for (let i = 0; i < nameArray.length; i += 1) {
884
+ if (!Object.hasOwnProperty.call(thisName, nameArray[i])) {
885
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
886
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
887
+ return callback(null, errorObj);
888
+ }
889
+ thisName = thisName[nameArray[i]];
890
+ }
891
+ thisDevice.name = thisName;
892
+ let thisOstype = thisDevice;
893
+ for (let i = 0; i < ostypeArray.length; i += 1) {
894
+ if (!Object.hasOwnProperty.call(thisOstype, ostypeArray[i])) {
895
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
896
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
897
+ return callback(null, errorObj);
898
+ }
899
+ thisOstype = thisOstype[ostypeArray[i]];
900
+ }
901
+ thisDevice.ostype = ostypePrefix + thisOstype;
902
+ let thisPort = thisDevice;
903
+ for (let i = 0; i < portArray.length; i += 1) {
904
+ if (!Object.hasOwnProperty.call(thisPort, portArray[i])) {
905
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
906
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
907
+ return callback(null, errorObj);
908
+ }
909
+ thisPort = thisPort[portArray[i]];
910
+ }
911
+ thisDevice.port = thisPort;
912
+ let thisIp = thisDevice;
913
+ for (let i = 0; i < ipArray.length; i += 1) {
914
+ if (!Object.hasOwnProperty.call(thisIp, ipArray[i])) {
915
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['getDevicesFiltered'], null, null, null);
916
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
917
+ return callback(null, errorObj);
918
+ }
919
+ thisIp = thisIp[ipArray[i]];
920
+ }
921
+ thisDevice.ipaddress = thisIp;
922
+
923
+ // if there is no filter - return the device
924
+ if (filterName.length === 0) {
925
+ log.debug(`${origin}: Found #1 device.`);
926
+ log.debug(`Device: ${JSON.stringify(thisDevice)}`);
927
+ return callback({ total: 1, list: [thisDevice] });
928
+ }
929
+
930
+ // if there is a filter need to check for matching device
931
+ let found = false;
932
+ for (let f = 0; f < filterName.length; f += 1) {
933
+ if (thisDevice.name.indexOf(filterName[f]) >= 0) {
934
+ found = true;
935
+ break;
936
+ }
937
+ }
938
+ // matching device
939
+ if (found) {
940
+ log.debug(`${origin}: Found #1 device.`);
941
+ log.debug(`Device Found: ${JSON.stringify(thisDevice)}`);
942
+ return callback({ total: 1, list: [thisDevice] });
943
+ }
944
+ // not a matching device
945
+ log.debug(`${origin}: No matching device found.`);
946
+ return callback({ total: 0, list: [] });
947
+ });
948
+ } catch (ex) {
949
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
950
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
951
+ return callback(null, errorObj);
952
+ }
953
+ }
954
+
955
+ /**
956
+ * @summary Gets the status for the provided appliance
957
+ *
958
+ * @function isAlive
959
+ * @param {String} deviceName - the deviceName of the appliance. (required)
960
+ *
961
+ * @param {configCallback} callback - callback function to return the result
962
+ * (appliance isAlive) or the error
963
+ */
964
+ isAlive(deviceName, callback) {
965
+ const meth = 'adapter-isAlive';
966
+ const origin = `${this.id}-${meth}`;
967
+ log.trace(origin);
968
+
969
+ // make sure we are set up for device broker isAlive
970
+ if (!this.props.devicebroker || !this.props.devicebroker.isAlive || !this.props.devicebroker.isAlive.path) {
971
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.isAlive.path'], null, null, null);
972
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
973
+ return callback(null, errorObj);
974
+ }
975
+
976
+ // verify the required fields have been provided
977
+ if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
978
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
979
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
980
+ return callback(null, errorObj);
981
+ }
982
+
983
+ try {
984
+ // need to get the device so we can convert the deviceName to an id
985
+ // !! if we can do a lookup by name the getDevicesFiltered may not be necessary
986
+ const opts = {
987
+ filter: {
988
+ name: deviceName
989
+ }
990
+ };
991
+ return this.getDevicesFiltered(opts, (devs, ferr) => {
992
+ // if we received an error or their is no response on the results return an error
993
+ if (ferr) {
994
+ return callback(null, ferr);
995
+ }
996
+ if (devs.list.length < 1) {
997
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
998
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
999
+ return callback(null, errorObj);
1000
+ }
1001
+ // get the uuid from the device
1002
+ const { uuid } = devs.list[0];
1003
+
1004
+ // !! using Generic makes it easier on the Adapter Builder (just need to change the path)
1005
+ // !! you can also replace with a specific call if that is easier
1006
+ let uriPath = '';
1007
+ let uriMethod = 'GET';
1008
+ let callQuery = {};
1009
+ let callBody = {};
1010
+ let callHeaders = {};
1011
+ let statusField = 'status';
1012
+ let statusArray = ['status'];
1013
+ let statusValue = 'true';
1014
+ if (this.props.devicebroker.isAlive.path) {
1015
+ uriPath = `${this.props.devicebroker.isAlive.path}`;
1016
+ uriPath = uriPath.replace('{deviceid}', uuid);
1017
+ }
1018
+ if (this.props.devicebroker.isAlive.method) {
1019
+ uriMethod = this.props.devicebroker.isAlive.method;
1020
+ }
1021
+ if (this.props.devicebroker.isAlive.query) {
1022
+ try {
1023
+ callQuery = this.props.devicebroker.isAlive.query;
1024
+ } catch (e) {
1025
+ log.warn('Could not parse query parameter for isAlive call');
1026
+ }
1027
+ }
1028
+ if (this.props.devicebroker.isAlive.body) {
1029
+ try {
1030
+ callBody = this.props.devicebroker.isAlive.body;
1031
+ } catch (e) {
1032
+ log.warn('Could not parse body for isAlive call');
1033
+ }
1034
+ }
1035
+ if (this.props.devicebroker.isAlive.headers) {
1036
+ try {
1037
+ callHeaders = this.props.devicebroker.isAlive.headers;
1038
+ } catch (e) {
1039
+ log.warn('Could not parse headers for isAlive call');
1040
+ }
1041
+ }
1042
+ if (this.props.devicebroker.isAlive.response && this.props.devicebroker.isAlive.status_field) {
1043
+ statusField = this.props.devicebroker.isAlive.status_field;
1044
+ statusArray = statusField.split('.');
1045
+ }
1046
+ if (this.props.devicebroker.isAlive.response && this.props.devicebroker.isAlive.status_value) {
1047
+ statusValue = this.props.devicebroker.isAlive.response.status_value;
1048
+ }
1049
+
1050
+ return this.genericAdapterRequest(uriPath, uriMethod, callQuery, callBody, callHeaders, (result, error) => {
1051
+ // if we received an error or their is no response on the results return an error
1052
+ if (error) {
1053
+ return callback(null, error);
1054
+ }
1055
+
1056
+ // !! should update this to make sure we are checking for the appropriate object/field
1057
+ if (!result.response || !result.response.returnObj) {
1058
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['isAlive'], null, null, null);
1059
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1060
+ return callback(null, errorObj);
1061
+ }
1062
+ let thisObj = result.response.returnObj;
1063
+ for (let i = 0; i < statusArray.length; i += 1) {
1064
+ if (!Object.hasOwnProperty.call(thisObj, statusArray[i])) {
1065
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Invalid Response', ['isAlive'], null, null, null);
1066
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1067
+ return callback(null, errorObj);
1068
+ }
1069
+ thisObj = thisObj[statusArray[i]];
1070
+ }
1071
+
1072
+ // !! return the response - Update to the appropriate object/field
1073
+ let response = true;
1074
+ if (thisObj.toString() !== statusValue) {
1075
+ response = false;
1076
+ }
1077
+ return callback(response);
1078
+ });
1079
+ });
1080
+ } catch (ex) {
1081
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
1082
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1083
+ return callback(null, errorObj);
1084
+ }
1085
+ }
1086
+
1087
+ /**
1088
+ * @summary Gets a config for the provided Appliance
1089
+ *
1090
+ * @function getConfig
1091
+ * @param {String} deviceName - the deviceName of the appliance. (required)
1092
+ * @param {String} format - the desired format of the config. (optional)
1093
+ *
1094
+ * @param {configCallback} callback - callback function to return the result
1095
+ * (appliance config) or the error
1096
+ */
1097
+ getConfig(deviceName, format, callback) {
1098
+ const meth = 'adapter-getConfig';
1099
+ const origin = `${this.id}-${meth}`;
1100
+ log.trace(origin);
1101
+
1102
+ // make sure we are set up for device broker getConfig
1103
+ if (!this.props.devicebroker || !this.props.devicebroker.getConfig || !this.props.devicebroker.getConfig.path) {
1104
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getConfig.path'], null, null, null);
1105
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1106
+ return callback(null, errorObj);
1107
+ }
1108
+
1109
+ // verify the required fields have been provided
1110
+ if (deviceName === undefined || deviceName === null || deviceName === '' || deviceName.length === 0) {
1111
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Data', ['deviceName'], null, null, null);
1112
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1113
+ return callback(null, errorObj);
1114
+ }
1115
+
1116
+ try {
1117
+ // need to get the device so we can convert the deviceName to an id
1118
+ // !! if we can do a lookup by name the getDevicesFiltered may not be necessary
1119
+ const opts = {
1120
+ filter: {
1121
+ name: deviceName
1122
+ }
1123
+ };
1124
+ return this.getDevicesFiltered(opts, (devs, ferr) => {
1125
+ // if we received an error or their is no response on the results return an error
1126
+ if (ferr) {
1127
+ return callback(null, ferr);
1128
+ }
1129
+ if (devs.list.length < 1) {
1130
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, `Did Not Find Device ${deviceName}`, [], null, null, null);
1131
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1132
+ return callback(null, errorObj);
1133
+ }
1134
+ // get the uuid from the device
1135
+ const { uuid } = devs.list[0];
1136
+
1137
+ // !! using Generic makes it easier on the Adapter Builder (just need to change the path)
1138
+ // !! you can also replace with a specific call if that is easier
1139
+ let uriPath = '';
1140
+ let uriMethod = 'GET';
1141
+ let callQuery = {};
1142
+ let callBody = {};
1143
+ let callHeaders = {};
1144
+ if (this.props.devicebroker.getConfig.path) {
1145
+ uriPath = `${this.props.devicebroker.getConfig.path}`;
1146
+ uriPath = uriPath.replace('{deviceid}', uuid);
1147
+ }
1148
+ if (this.props.devicebroker.getConfig.method) {
1149
+ uriMethod = this.props.devicebroker.getConfig.method;
1150
+ }
1151
+ if (this.props.devicebroker.getConfig.query) {
1152
+ try {
1153
+ callQuery = this.props.devicebroker.getConfig.query;
1154
+ } catch (e) {
1155
+ log.warn('Could not parse query parameter for getConfig call');
1156
+ }
1157
+ }
1158
+ if (this.props.devicebroker.getConfig.body) {
1159
+ try {
1160
+ callBody = this.props.devicebroker.getConfig.body;
1161
+ } catch (e) {
1162
+ log.warn('Could not parse body for getConfig call');
1163
+ }
1164
+ }
1165
+ if (this.props.devicebroker.getConfig.headers) {
1166
+ try {
1167
+ callHeaders = this.props.devicebroker.getConfig.headers;
1168
+ } catch (e) {
1169
+ log.warn('Could not parse headers for getConfig call');
1170
+ }
1171
+ }
1172
+
1173
+ return this.genericAdapterRequest(uriPath, uriMethod, callQuery, callBody, callHeaders, (result, error) => {
1174
+ // if we received an error or their is no response on the results return an error
1175
+ if (error) {
1176
+ return callback(null, error);
1177
+ }
1178
+
1179
+ // return the result
1180
+ const newResponse = {
1181
+ response: JSON.stringify(result.response, null, 2)
1182
+ };
1183
+ return callback(newResponse);
1184
+ });
1185
+ });
1186
+ } catch (ex) {
1187
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
1188
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1189
+ return callback(null, errorObj);
1190
+ }
1191
+ }
1192
+
1193
+ /**
1194
+ * @summary Gets the device count from the system
1195
+ *
1196
+ * @function iapGetDeviceCount
1197
+ *
1198
+ * @param {getCallback} callback - callback function to return the result
1199
+ * (count) or the error
1200
+ */
1201
+ iapGetDeviceCount(callback) {
1202
+ const meth = 'adapter-iapGetDeviceCount';
1203
+ const origin = `${this.id}-${meth}`;
1204
+ log.trace(origin);
1205
+
1206
+ // make sure we are set up for device broker getCount
1207
+ if (!this.props.devicebroker || !this.props.devicebroker.getCount || !this.props.devicebroker.getCount.path) {
1208
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Missing Properties', ['devicebroker.getCount.path'], null, null, null);
1209
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1210
+ return callback(null, errorObj);
1211
+ }
1212
+
1213
+ // verify the required fields have been provided
1214
+
1215
+ try {
1216
+ // !! using Generic makes it easier on the Adapter Builder (just need to set the path or call in properties)
1217
+ // !! you can also replace with a specific call if that is easier
1218
+ let uriPath = '';
1219
+ let uriMethod = 'GET';
1220
+ let callQuery = {};
1221
+ let callBody = {};
1222
+ let callHeaders = {};
1223
+ if (this.props.devicebroker.getCount.path) {
1224
+ uriPath = this.props.devicebroker.getCount.path;
1225
+ }
1226
+ if (this.props.devicebroker.getCount.method) {
1227
+ uriMethod = this.props.devicebroker.getCount.method;
1228
+ }
1229
+ if (this.props.devicebroker.getCount.query) {
1230
+ try {
1231
+ callQuery = this.props.devicebroker.getCount.query;
1232
+ } catch (e) {
1233
+ log.warn('Could not parse query parameter for getCount call');
1234
+ }
1235
+ }
1236
+ if (this.props.devicebroker.getCount.body) {
1237
+ try {
1238
+ callBody = this.props.devicebroker.getCount.body;
1239
+ } catch (e) {
1240
+ log.warn('Could not parse body for getCount call');
1241
+ }
1242
+ }
1243
+ if (this.props.devicebroker.getCount.headers) {
1244
+ try {
1245
+ callHeaders = this.props.devicebroker.getCount.headers;
1246
+ } catch (e) {
1247
+ log.warn('Could not parse headers for getCount call');
1248
+ }
1249
+ }
1250
+
1251
+ return this.genericAdapterRequest(uriPath, uriMethod, callQuery, callBody, callHeaders, (result, error) => {
1252
+ // if we received an error or their is no response on the results return an error
1253
+ if (error) {
1254
+ return callback(null, error);
1255
+ }
1256
+
1257
+ // return the result
1258
+ return callback({ count: result.response });
1259
+ });
1260
+ } catch (ex) {
1261
+ const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'Caught Exception', null, null, null, ex);
1262
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1263
+ return callback(null, errorObj);
1264
+ }
1265
+ }
1266
+
1267
+ /* GENERIC ADAPTER REQUEST - allows extension of adapter without new calls being added */
421
1268
  /**
422
1269
  * Makes the requested generic call
423
1270
  *
@@ -22405,7 +23252,7 @@ class Meraki extends AdapterBaseCl {
22405
23252
  const queryParamsAvailable = {};
22406
23253
  const queryParams = {};
22407
23254
  const pathVars = [organizationId, licenseId];
22408
- const bodyVars = { body };
23255
+ const bodyVars = body;
22409
23256
 
22410
23257
  // loop in template. long callback arg name to avoid identifier conflicts
22411
23258
  Object.keys(queryParamsAvailable).forEach((thisKeyInQueryParamsAvailable) => {
@@ -22480,7 +23327,7 @@ class Meraki extends AdapterBaseCl {
22480
23327
  const queryParamsAvailable = {};
22481
23328
  const queryParams = {};
22482
23329
  const pathVars = [organizationId];
22483
- const bodyVars = { body };
23330
+ const bodyVars = body;
22484
23331
 
22485
23332
  // loop in template. long callback arg name to avoid identifier conflicts
22486
23333
  Object.keys(queryParamsAvailable).forEach((thisKeyInQueryParamsAvailable) => {
@@ -22555,7 +23402,7 @@ class Meraki extends AdapterBaseCl {
22555
23402
  const queryParamsAvailable = {};
22556
23403
  const queryParams = {};
22557
23404
  const pathVars = [organizationId];
22558
- const bodyVars = { body };
23405
+ const bodyVars = body;
22559
23406
 
22560
23407
  // loop in template. long callback arg name to avoid identifier conflicts
22561
23408
  Object.keys(queryParamsAvailable).forEach((thisKeyInQueryParamsAvailable) => {
@@ -22630,7 +23477,7 @@ class Meraki extends AdapterBaseCl {
22630
23477
  const queryParamsAvailable = {};
22631
23478
  const queryParams = {};
22632
23479
  const pathVars = [organizationId];
22633
- const bodyVars = { body };
23480
+ const bodyVars = body;
22634
23481
 
22635
23482
  // loop in template. long callback arg name to avoid identifier conflicts
22636
23483
  Object.keys(queryParamsAvailable).forEach((thisKeyInQueryParamsAvailable) => {
@@ -22705,7 +23552,7 @@ class Meraki extends AdapterBaseCl {
22705
23552
  const queryParamsAvailable = {};
22706
23553
  const queryParams = {};
22707
23554
  const pathVars = [organizationId];
22708
- const bodyVars = { body };
23555
+ const bodyVars = body;
22709
23556
 
22710
23557
  // loop in template. long callback arg name to avoid identifier conflicts
22711
23558
  Object.keys(queryParamsAvailable).forEach((thisKeyInQueryParamsAvailable) => {