@carlosbajo/micro
Version:
framework para microservicios con google/pubsub
130 lines (118 loc) • 3.62 kB
JavaScript
/**
* 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.
*/
;
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;