Files
SenMeshNet/electron/bridges/inspection/adapters/baseAdapter.cjs

128 lines
3.1 KiB
JavaScript
Raw Normal View History

"use strict";
/**
* 采集器基类
*
* 所有设备采集器都继承此类,统一采集接口。
* 采集器负责:
* 1. 建立 SSH 连接
* 2. 执行巡检命令
* 3. 解析输出为结构化指标数据
* 4. 关闭连接
*
* 子类需实现:
* - getSupportedMetrics() 返回支持的指标列表
* - collectMetrics() 执行所有采集命令并返回结构化指标
*/
const { INSPECTION_STATUS } = require("../types.cjs");
class BaseAdapter {
/**
* @param {object} connectionInfo - SSH 连接信息
* @param {string} connectionInfo.host - 主机 IP
* @param {number} connectionInfo.port - 端口
* @param {string} connectionInfo.username - 用户名
* @param {string} [connectionInfo.password] - 密码
* @param {string} [connectionInfo.privateKey] - 私钥
* @param {object} [options]
* @param {number} [options.timeoutMs] - 单条命令超时(毫秒)
*/
constructor(connectionInfo, options = {}) {
this.connectionInfo = connectionInfo;
this.timeoutMs = options.timeoutMs || 15000;
this.conn = null;
}
/**
* 建立连接
* 子类可以覆盖此方法实现不同的连接方式(如 Telnet)
* @returns {Promise<boolean>}
*/
async connect() {
// 基类不实现具体连接逻辑,由上层调度器负责 SSH 连接
// 或者由子类自行实现
return true;
}
/**
* 执行单条命令
* 由子类或注入的 exec 函数实现
* @param {string} command
* @returns {Promise<string>}
*/
async execute(command) {
throw new Error("execute() must be implemented by subclass or injected");
}
/**
* 关闭连接
*/
async disconnect() {
// 子类可覆盖
}
/**
* 获取支持的指标列表
* @returns {string[]}
*/
getSupportedMetrics() {
throw new Error("getSupportedMetrics() must be implemented by subclass");
}
/**
* 执行完整巡检,返回结构化指标数据
* @returns {Promise<object>}
* {
* online: boolean,
* metrics: { ... },
* raw: { ... } // 原始输出(调试用)
* }
*/
async collect() {
const result = {
online: false,
metrics: {},
raw: {},
error: null,
status: INSPECTION_STATUS.SUCCESS,
};
try {
const metrics = await this.collectMetrics();
result.online = true;
result.metrics = metrics;
} catch (err) {
result.error = err.message;
result.status = err.message.includes("timeout")
? INSPECTION_STATUS.TIMEOUT
: INSPECTION_STATUS.FAILED;
}
return result;
}
/**
* 子类实现:具体的采集逻辑
* @returns {Promise<object>} 结构化指标数据
*/
async collectMetrics() {
throw new Error("collectMetrics() must be implemented by subclass");
}
/**
* 安全地从字符串中提取数字
* @param {string} text
* @param {RegExp} regex
* @returns {number|null}
*/
extractNumber(text, regex) {
const match = (text || "").match(regex);
if (!match) return null;
const num = parseFloat(match[1]);
return isNaN(num) ? null : num;
}
}
module.exports = BaseAdapter;