// src/integrations/webex/XapiClient.js import webex from './WebexClient.js'; // reuse the main client for auth (xapi calls now delegate to it for consistency + retry) import { logger } from '../../utils/logger.js'; class XapiClient { static #instance = null; constructor() { if (XapiClient.#instance) { return XapiClient.#instance; } XapiClient.#instance = this; logger('webex:xapi', 'XapiClient initialized (delegates xapi to WebexClient.request)'); } async xCommand(command, payload = {}) { // Delegate to webex.request (same pattern used by vcProvision for all xapi/command/* calls). // Benefits: automatic 401 retry + token handling + consistent error surfacing. try { const data = await webex.request('POST', `xapi/command/${command}`, payload); logger('webex:xapi', `xCommand ${command} succeeded`); return data; } catch (err) { const errorDetail = err.response?.data?.message || err.response?.data || err.message; logger('webex:xapi', `xCommand ${command} failed: ${errorDetail}`, 'error'); throw err; } } async xConfiguration(deviceId, path, value) { logger('webex:xapi', `Setting configuration: ${path} = ${value} on device ${deviceId}`); return this.xCommand('xConfiguration', { deviceId, arguments: { Path: path, Value: value } }); } /** * Execute an xCommand on a device (e.g. Logging.ExtendedLogging.Start). * Convenience wrapper: pass deviceId + flat arguments object. */ async xCommandWithDevice(commandKey, deviceId, argumentsObj = {}) { return this.xCommand(commandKey, { deviceId, arguments: argumentsObj }); } /** * Query xStatus on a device (subtree). * Example: xStatus(deviceId, 'Logging.ExtendedLogging') * * Per cloud xAPI (and vcProvision xapi call patterns): * GET /v1/xapi/status?deviceId=...&name=Logging.ExtendedLogging * Response shape: { deviceId, result: { Logging: { ExtendedLogging: { Mode, PacketDump, ... } } } } * Uses webex.request for 401-retry consistency with other xapi/* calls in the project. */ async xStatus(deviceId, name = '') { const params = { deviceId }; if (name) { params.name = name; // e.g. "Logging.ExtendedLogging" or "Logging.ExtendedLogging.Mode" (dot notation) } try { const data = await webex.request('GET', 'xapi/status', null, params); logger('webex:xapi', `xStatus ${name || '(root)'} succeeded for device`); return data; } catch (err) { const errorDetail = err.response?.data?.message || err.response?.data || err.message; logger('webex:xapi', `xStatus ${name} failed: ${errorDetail}`, 'error'); throw err; } } } // Export singleton instance export default new XapiClient();