coddyger
Version:
Coddyger est une bibliothèque JavaScript/TypeScript qui fournit des fonctions communes et des plugins pour la gestion des données, la communication entre services, et des utilitaires avancés pour le développement d'applications.
269 lines (268 loc) • 10.6 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransporterService = void 0;
const kafkajs_1 = require("kafkajs");
const globals_1 = __importDefault(require("../globals"));
const logger_service_1 = require("./logger.service");
const coddyger_1 = __importDefault(require("../coddyger"));
function logError(error, location, method) {
return __awaiter(this, void 0, void 0, function* () {
logger_service_1.LoggerService.log({
type: logger_service_1.LogLevel.Error,
content: JSON.stringify(error),
location,
method
});
});
}
function handleRemove(dao, _id, label) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield dao.remove({ _id });
if (result.error) {
yield logError(result, 'TransporterCore', `${label}-remove`);
}
else {
coddyger_1.default.konsole(`${label} removed successfully :: ${_id}`);
}
});
}
function handleCreate(dao, data, label) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield dao.save(data);
if (result.error) {
yield logError(result, 'TransporterCore', `${label}-save`);
}
else {
coddyger_1.default.konsole(`${label} saved successfully :: ${data._id}`);
}
});
}
function handleUpdate(dao, _id, data, label) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield dao.update({ _id }, data);
if (result.error) {
yield logError(result, 'TransporterCore', `${label}-update`);
}
else {
coddyger_1.default.konsole(`${label} edited successfully :: ${_id}`);
}
});
}
function handleNoCrud(data, handler, label) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield handler(data);
coddyger_1.default.konsole(`${label} no-crud action executed successfully`);
}
catch (error) {
yield logError(error, 'TransporterCore', `${label}-no-crud`);
}
});
}
function getData(data, set, label) {
return __awaiter(this, void 0, void 0, function* () {
const _id = data._id;
const dao = new set();
try {
if (!_id) {
throw new Error('Missing _id in data');
}
if (!coddyger_1.default.string.isValidObjectId(_id)) {
yield logError('Wrong _id detected::' + _id, 'TransporterCore', 'getData');
return;
}
if (data.action === 'remove') {
yield handleRemove(dao, _id, label);
return;
}
const existResult = yield dao.exist({ _id });
if (existResult && typeof existResult === 'object' && 'error' in existResult) {
yield logError(existResult.error, 'TransporterCore', `${label}-exist`);
return;
}
if (!existResult) {
yield handleCreate(dao, data, label);
}
else {
const { _id } = data, updateData = __rest(data, ["_id"]);
yield handleUpdate(dao, _id, updateData, label);
}
}
catch (error) {
yield logError(error, 'TransporterCore', 'getData');
}
});
}
class TransporterService {
constructor(topics) {
this.topics = [];
this.isConnected = false;
this.reconnectAttempts = 0;
this.MAX_RECONNECT_ATTEMPTS = 5;
this.kafka = new kafkajs_1.Kafka({
clientId: globals_1.default.transporter.client,
brokers: globals_1.default.transporter.broker.split(','),
logLevel: kafkajs_1.logLevel.ERROR
});
this.producer = this.kafka.producer();
this.consumer = this.kafka.consumer({
groupId: globals_1.default.transporter.group
});
this.topics = topics || [];
}
send(value, topic) {
return __awaiter(this, void 0, void 0, function* () {
try {
if (!this.isConnected) {
yield this.connect();
}
yield this.producer.send({
topic: !coddyger_1.default.string.isEmpty(topic) ? topic : globals_1.default.transporter.topic,
messages: [{ value }]
});
}
catch (error) {
yield logError(error, 'TransporterService', 'send');
throw error;
}
});
}
connect() {
return __awaiter(this, void 0, void 0, function* () {
try {
yield Promise.all([
this.producer.connect(),
this.consumer.connect()
]);
this.isConnected = true;
this.reconnectAttempts = 0;
coddyger_1.default.konsole(`Transporter connected! :: ${globals_1.default.transporter.broker}`);
}
catch (error) {
this.isConnected = false;
yield logError(error, 'TransporterService', 'connect');
throw error;
}
});
}
disconnect() {
return __awaiter(this, void 0, void 0, function* () {
try {
yield Promise.all([
this.producer.disconnect(),
this.consumer.disconnect()
]);
this.isConnected = false;
coddyger_1.default.konsole('Transporter disconnected successfully');
}
catch (error) {
yield logError(error, 'TransporterService', 'disconnect');
throw error;
}
});
}
handleReconnect() {
return __awaiter(this, void 0, void 0, function* () {
if (this.reconnectAttempts >= this.MAX_RECONNECT_ATTEMPTS) {
yield logError('Max reconnection attempts reached', 'TransporterService', 'handleReconnect');
return;
}
this.reconnectAttempts++;
try {
yield this.connect();
}
catch (error) {
yield logError(error, 'TransporterService', 'handleReconnect');
setTimeout(() => this.handleReconnect(), 5000 * this.reconnectAttempts);
}
});
}
handleEvent(data, topic) {
return __awaiter(this, void 0, void 0, function* () {
const action = data.action;
if (action === 'remove' && topic.set) {
yield getData(data, topic.set, topic.id);
return;
}
if (topic.handlers && topic.handlers[action]) {
try {
yield topic.handlers[action](data);
coddyger_1.default.konsole(`Event ${action} handled successfully for topic ${topic.id}`);
return;
}
catch (error) {
yield logError(error, 'TransporterService', `${topic.id}-${action}`);
return;
}
}
if (topic.set && !action) {
yield getData(data, topic.set, topic.id);
return;
}
yield logError(`No handler found for action ${action} in topic ${topic.id}`, 'TransporterService', 'handleEvent');
});
}
get() {
return __awaiter(this, void 0, void 0, function* () {
try {
yield this.connect();
for (const topic of this.topics) {
yield this.consumer.subscribe({
topic: topic.id,
fromBeginning: true
});
}
yield this.consumer.run({
eachMessage: (payload) => __awaiter(this, void 0, void 0, function* () {
try {
const msg = {
partition: payload.partition,
offset: payload.message.offset,
value: payload.message.value.toString()
};
coddyger_1.default.konsole(`Consuming from :: ${payload.topic}`);
const data = JSON.parse(msg.value);
for (const topic of this.topics) {
if (payload.topic === topic.id) {
yield this.handleEvent(data, topic);
}
}
}
catch (error) {
yield logError(error, 'TransporterService', 'eachMessage');
}
}),
autoCommit: true
});
}
catch (error) {
yield logError(error, 'TransporterService', 'get');
yield this.handleReconnect();
}
});
}
}
exports.TransporterService = TransporterService;