@frankvdb/node-red-contrib-amqp
Version:
RabbitMQ nodes for node-red
95 lines (94 loc) • 3.57 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const types_1 = require("../types");
module.exports = function (RED) {
const brokerNodes = [];
const amqpNodeTypes = new Set([
types_1.NodeType.AmqpIn,
types_1.NodeType.AmqpInManualAck,
types_1.NodeType.AmqpOut,
]);
function AmqpBroker(n) {
// wtf happened to the types?
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
RED.nodes.createNode(this, n);
this.name = n.name;
this.host = n.host;
this.port = n.port;
this.tls = n.tls;
this.vhost = n.vhost;
this.credsFromSettings = n.credsFromSettings;
this.nodeStates = n.nodeStates || {};
this.lastError = n.lastError || {};
brokerNodes.push(this);
this.on('close', () => {
const index = brokerNodes.indexOf(this);
/* istanbul ignore else */
if (index > -1) {
brokerNodes.splice(index, 1);
}
});
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
RED.nodes.registerType('amqp-broker', AmqpBroker, {
credentials: {
username: { type: 'text' },
password: { type: 'password' },
},
});
RED.httpAdmin.get('/amqp-broker/health', (_req, res) => {
const brokerStatuses = brokerNodes.map(brokerNode => {
const states = getEffectiveNodeStates(brokerNode);
const stateValues = Object.values(states);
const uniqueStates = new Set(stateValues);
const status = stateValues.length > 0 && stateValues.every(state => state === 'connected')
? 'connected'
: uniqueStates.has('errored')
? 'errored'
: 'disconnected';
const brokerStatus = {
id: brokerNode.id,
name: brokerNode.name,
status,
};
const activeLastError = getActiveLastError(brokerNode, states);
const hasLastError = Object.keys(activeLastError).length > 0;
if (hasLastError) {
brokerStatus.lastError = activeLastError;
}
return brokerStatus;
});
const hasBrokers = brokerStatuses.length > 0;
const allConnected = hasBrokers && brokerStatuses.every(b => b.status === 'connected');
const statusCode = allConnected ? 200 : 503;
const response = {
overallStatus: allConnected ? 'healthy' : 'unhealthy',
brokers: brokerStatuses,
};
res.status(statusCode).json(response);
});
function getEffectiveNodeStates(brokerNode) {
var _a;
const states = {};
const nodes = RED.nodes;
(_a = nodes.eachNode) === null || _a === void 0 ? void 0 : _a.call(nodes, node => {
var _a;
if (node.broker === brokerNode.id && amqpNodeTypes.has(node.type)) {
states[node.id] = ((_a = brokerNode.nodeStates) === null || _a === void 0 ? void 0 : _a[node.id]) || 'disconnected';
}
});
return states;
}
function getActiveLastError(brokerNode, states) {
const source = brokerNode.lastError || {};
const filtered = {};
Object.keys(states).forEach(nodeId => {
if (source[nodeId]) {
filtered[nodeId] = source[nodeId];
}
});
return filtered;
}
};