UNPKG

@fiqch/n8n-nodes-fiq-opcua

Version:

n8n custom node for reading and writing OPC UA data (FactoryIQ)

171 lines 6.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OpcUaConnectionPool = void 0; const vendor_1 = require("../../../vendor"); class OpcUaConnectionPool { constructor() { this.pools = new Map(); } static getInstance() { if (!this.instance) { this.instance = new OpcUaConnectionPool(); } return this.instance; } async getConnection(credentials) { const key = this.createKey(credentials); let pool = this.pools.get(key) || []; for (const conn of pool) { if (!conn.inUse && conn.session && !conn.session.isReconnecting) { try { if (conn.session.isChannelValid && conn.session.isChannelValid()) { conn.inUse = true; return conn; } } catch (error) { const index = pool.indexOf(conn); if (index > -1) { pool.splice(index, 1); } } } } if (pool.length < 3) { try { const newConn = await this.createConnection(credentials, key); newConn.inUse = true; pool.push(newConn); this.pools.set(key, pool); return newConn; } catch (error) { throw error; } } const conn = pool[0]; conn.inUse = true; return conn; } releaseConnection(connection) { if (connection) { connection.inUse = false; } } createKey(credentials) { const endpointUrl = credentials.endpointUrl; const authenticationType = credentials.authenticationType || 'anonymous'; const username = credentials.username || ''; return `${endpointUrl}|${authenticationType}|${username}`; } async createConnection(credentials, key) { const endpointUrl = credentials.endpointUrl; const securityPolicy = credentials.securityPolicy || 'None'; const securityMode = credentials.securityMode || 'None'; const authenticationType = credentials.authenticationType || 'anonymous'; let securityPolicyEnum; let securityModeEnum; switch (securityPolicy) { case 'Basic256Sha256': securityPolicyEnum = vendor_1.SecurityPolicy.Basic256Sha256; break; case 'Basic256': securityPolicyEnum = vendor_1.SecurityPolicy.Basic256; break; case 'Basic128Rsa15': securityPolicyEnum = vendor_1.SecurityPolicy.Basic128Rsa15; break; case 'Aes128_Sha256_RsaOaep': securityPolicyEnum = vendor_1.SecurityPolicy.Aes128_Sha256_RsaOaep; break; case 'Aes256_Sha256_RsaPss': securityPolicyEnum = vendor_1.SecurityPolicy.Aes256_Sha256_RsaPss; break; default: securityPolicyEnum = vendor_1.SecurityPolicy.None; } switch (securityMode) { case 'Sign': securityModeEnum = vendor_1.MessageSecurityMode.Sign; break; case 'SignAndEncrypt': case 'Sign & Encrypt': securityModeEnum = vendor_1.MessageSecurityMode.SignAndEncrypt; break; default: securityModeEnum = vendor_1.MessageSecurityMode.None; } const randomSuffix = Math.random().toString(36).substring(2, 10); const clientName = `n8n-opcua-pool-${randomSuffix}`; const clientOptions = { securityPolicy: securityPolicyEnum, securityMode: securityModeEnum, connectionStrategy: { initialDelay: 1000, maxRetry: 3, maxDelay: 10000, }, clientName, requestedSessionTimeout: 60000, endpointMustExist: false, securityOptions: { rejectUnauthorized: false } }; if (authenticationType === 'x509') { if (credentials.certificate && credentials.privateKey) { clientOptions.certificateData = Buffer.from(credentials.certificate); clientOptions.privateKeyData = Buffer.from(credentials.privateKey); } else { throw new Error('X509 authentication requires both certificate and private key.'); } } const client = vendor_1.OPCUAClient.create(clientOptions); await client.connect(endpointUrl); let userIdentity; if (authenticationType === 'usernamePassword') { userIdentity = { type: vendor_1.UserTokenType.UserName, userName: credentials.username, password: credentials.password, }; } else if (authenticationType === 'x509') { userIdentity = { type: vendor_1.UserTokenType.Certificate, certificateData: credentials.certificate, privateKey: credentials.privateKey, }; } else { userIdentity = undefined; } const session = await client.createSession(userIdentity); return { client, session, inUse: false, key }; } async shutdown() { for (const pool of this.pools.values()) { for (const conn of pool) { try { if (conn.session) { await conn.session.close(); } if (conn.client) { await conn.client.disconnect(); } } catch (error) { } } } this.pools.clear(); } } exports.OpcUaConnectionPool = OpcUaConnectionPool; //# sourceMappingURL=ConnectionPool.js.map