UNPKG

@carlosbajo/micro

Version:

framework para microservicios con google/pubsub

130 lines (118 loc) 3.62 kB
/** * Validaciones : * 1.- Falta validar que cuando este en local o produccion no se solicite el sasl * 2.- Se tiene que eliminar el archivo pubsub.js ya no es necesario * 3.- Falta implementar error reporter * 4.- Falta implementar trace * 5.- Implementar Circuit Breaker * 6.- Control de fallos. */ 'use strict'; const { Kafka } = require('kafkajs'); const { name } = require(`${process.cwd()}/package.json`); const uuidPackage = require('uuid'); const environment = process.env.NODE_ENV; class Pubsub { constructor() { const host = process.env.KAFKA_ADDRESS || '192.168.8.14'; const sasl = environment === 'local' ? null : { mechanism: 'plain', // scram-sha-256 or scram-sha-512 username: process.env.KAFKA_USER, password: process.env.KAFKA_PASSWORD, }; this.kafka = new Kafka({ brokers: [`${host}:9092`], clientId: `${name}_client`, sasl, }); this.consumer = this.kafka.consumer({ groupId: `${name}consumer` }); this.producer = this.kafka.producer(); this.admin = this.kafka.admin(); this.reqResources = {}; } nameTopic(topic) { return `${process.env.NODE_ENV}.${topic}`; } async getMicroTopics(deleteTopics = []) { await this.admin.connect(); const { topics } = await this.admin.fetchTopicMetadata(); let allTopics = []; for (let i = 0; i < deleteTopics.length; i++) { const microtopic = topics.filter(topic => topic.name.includes(`micro.${deleteTopics[i]}.`) ); allTopics = allTopics.concat(microtopic); } await this.admin.disconnect(); return allTopics; } async openConnection() { await this.consumer.connect(); await this.producer.connect(); } async rpc(topic, args) { const envTopic = this.nameTopic(topic); return new Promise(async(resolve, reject) => { const id = uuidPackage(); try { const data = { uuid: id, arg: args || {} }; this.reqResources[id] = { resolve, reject }; await this.writeMessageToMicro(JSON.stringify(data), envTopic); } catch (e) { delete this.reqResources[id]; reject(e.toString()); } }); } async closeConnection() { await this.producer.disconnect(); await this.consumer.disconnect(); } // Carga las subscripciones de todos los topicos asociados. async loadSubscription(topic) { await this.consumer.subscribe({ topic: topic.req }); } async setUpProject(topics) { const admin = this.kafka.admin(); const proccesedTopics = topics.map(topic => ({ topic: topic.req })); const proccesedTopicsRes = topics.map(topic => ({ topic: topic.res })); const proccesedTopicsMicro = topics.map(topic => ({ topic: topic.micro })); const resulted = proccesedTopics.concat(proccesedTopicsRes); const withMicro = resulted.concat(proccesedTopicsMicro); await admin.connect(); await admin.createTopics({ topics: withMicro }); await admin.disconnect(); } async writeMessageToMicro(value, topic) { try { await this.producer.send({ topic, messages: [{ value, headers: { responseKind: 'micro' } }], }); } catch (e) { console.log(e); } } async writeMessageToTopic(value, topic, responseKind) { try { await this.producer.send({ topic: this.nameTopic(topic), messages: [ { value, headers: { responseKind, }, }, ], }); } catch (e) { console.log(e); } } } module.exports = Pubsub;