@golevelup/nestjs-rabbitmq
Version:
Badass RabbitMQ addons for NestJS
167 lines • 9.65 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var RabbitMQModule_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RabbitMQModule = void 0;
const nestjs_discovery_1 = require("@golevelup/nestjs-discovery");
const common_1 = require("@nestjs/common");
const constants_1 = require("@nestjs/common/constants");
const external_context_creator_1 = require("@nestjs/core/helpers/external-context-creator");
const lodash_1 = require("lodash");
const connection_1 = require("./amqp/connection");
const connectionManager_1 = require("./amqp/connectionManager");
const utils_1 = require("./amqp/utils");
const rabbitmq_module_definition_1 = require("./rabbitmq-module-definition");
const rabbitmq_constants_1 = require("./rabbitmq.constants");
const rabbitmq_decorators_1 = require("./rabbitmq.decorators");
const rabbitmq_factory_1 = require("./rabbitmq.factory");
let RabbitMQModule = RabbitMQModule_1 = class RabbitMQModule extends rabbitmq_module_definition_1.ConfigurableModuleClass {
constructor(discover, externalContextCreator, rpcParamsFactory, connectionManager, config) {
super();
this.discover = discover;
this.externalContextCreator = externalContextCreator;
this.rpcParamsFactory = rpcParamsFactory;
this.connectionManager = connectionManager;
this.logger = (config === null || config === void 0 ? void 0 : config.logger) || new common_1.Logger(RabbitMQModule_1.name);
}
static async AmqpConnectionFactory(config) {
const logger = (config === null || config === void 0 ? void 0 : config.logger) || new common_1.Logger(RabbitMQModule_1.name);
if (config == undefined) {
logger.log('RabbitMQ config not provided, skipping connection initialization.');
return undefined;
}
config.uri = (0, utils_1.converUriConfigObjectsToUris)(config.uri);
(0, utils_1.validateRabbitMqUris)(config.uri);
const connection = new connection_1.AmqpConnection(config);
this.connectionManager.addConnection(connection);
await connection.init();
logger.log('Successfully connected to RabbitMQ');
return connection;
}
static attach(connection) {
return {
module: RabbitMQModule_1,
providers: [
{
provide: connection_1.AmqpConnection,
useValue: connection,
},
rabbitmq_factory_1.RabbitRpcParamsFactory,
],
exports: [connection_1.AmqpConnection],
};
}
async onApplicationShutdown() {
var _a, _b;
(_b = (_a = this.logger).verbose) === null || _b === void 0 ? void 0 : _b.call(_a, 'Closing AMQP Connections');
await this.connectionManager.close();
this.connectionManager.clearConnections();
RabbitMQModule_1.bootstrapped = false;
}
async setupHandler(connection, discoveredMethod, config, handler) {
var _a, _b, _c;
const handlerDisplayName = `${discoveredMethod.parentClass.name}.${discoveredMethod.methodName} {${config.type}} -> ${((_a = config.queueOptions) === null || _a === void 0 ? void 0 : _a.channel) ? `${config.queueOptions.channel}::` : ''}${config.exchange}::${config.routingKey}::${config.queue || 'amqpgen'}`;
if (config.type === 'rpc' &&
!connection.configuration.enableDirectReplyTo) {
this.logger.warn(`Direct Reply-To Functionality is disabled. RPC handler ${handlerDisplayName} will not be registered`);
return;
}
this.logger.log(handlerDisplayName);
switch (config.type) {
case 'rpc':
return connection.createRpc(handler, config);
case 'subscribe':
if (config.batchOptions) {
return connection.createBatchSubscriber(handler, config, (_b = config === null || config === void 0 ? void 0 : config.queueOptions) === null || _b === void 0 ? void 0 : _b.consumerOptions);
}
return connection.createSubscriber(handler, config, discoveredMethod.methodName, (_c = config === null || config === void 0 ? void 0 : config.queueOptions) === null || _c === void 0 ? void 0 : _c.consumerOptions);
default:
throw new Error(`Unable to set up handler ${handlerDisplayName}. Unexpected handler type ${config.type}.`);
}
}
async onApplicationBootstrap() {
if (RabbitMQModule_1.bootstrapped) {
return;
}
RabbitMQModule_1.bootstrapped = true;
for (const connection of this.connectionManager.getConnections()) {
if (!connection.configuration.registerHandlers) {
this.logger.log('Skipping RabbitMQ Handlers due to configuration. This application instance will not receive messages over RabbitMQ');
continue;
}
this.logger.log('Initializing RabbitMQ Handlers');
let rabbitMeta = await this.discover.providerMethodsWithMetaAtKey(rabbitmq_constants_1.RABBIT_HANDLER);
if (connection.configuration.enableControllerDiscovery) {
this.logger.log('Searching for RabbitMQ Handlers in Controllers. You can not use NestJS HTTP-Requests in these controllers!');
rabbitMeta = rabbitMeta.concat(await this.discover.controllerMethodsWithMetaAtKey(rabbitmq_constants_1.RABBIT_HANDLER));
}
const grouped = (0, lodash_1.groupBy)(rabbitMeta, (x) => x.discoveredMethod.parentClass.name);
const providerKeys = Object.keys(grouped);
for (const key of providerKeys) {
this.logger.log(`Registering rabbitmq handlers from ${key}`);
await Promise.all(grouped[key].map(async ({ discoveredMethod, meta: config }) => {
if (config.connection &&
config.connection !== connection.configuration.name) {
return;
}
const handler = this.externalContextCreator.create(discoveredMethod.parentClass.instance, discoveredMethod.handler, discoveredMethod.methodName, constants_1.ROUTE_ARGS_METADATA, this.rpcParamsFactory, undefined, // contextId
undefined, // inquirerId
undefined, // options
rabbitmq_constants_1.RABBIT_CONTEXT_TYPE_KEY);
const moduleHandlerConfigRaw = connection.configuration.handlers[config.name || connection.configuration.defaultHandler || ''];
const moduleHandlerConfigs = Array.isArray(moduleHandlerConfigRaw)
? moduleHandlerConfigRaw
: [moduleHandlerConfigRaw];
await Promise.all(moduleHandlerConfigs.map((moduleHandlerConfig) => {
const mergedConfig = Object.assign(Object.assign({}, config), moduleHandlerConfig);
return this.setupHandler(connection, discoveredMethod, mergedConfig, handler);
}));
}));
}
}
}
};
RabbitMQModule.connectionManager = new connectionManager_1.AmqpConnectionManager();
RabbitMQModule.bootstrapped = false;
RabbitMQModule = RabbitMQModule_1 = __decorate([
(0, common_1.Module)({
imports: [nestjs_discovery_1.DiscoveryModule],
providers: [
{
provide: connectionManager_1.AmqpConnectionManager,
useFactory: async (config) => {
await RabbitMQModule_1.AmqpConnectionFactory(config);
return RabbitMQModule_1.connectionManager;
},
inject: [rabbitmq_constants_1.RABBIT_CONFIG_TOKEN],
},
{
provide: connection_1.AmqpConnection,
useFactory: async (config, connectionManager) => {
return connectionManager.getConnection((config === null || config === void 0 ? void 0 : config.name) || 'default');
},
inject: [rabbitmq_constants_1.RABBIT_CONFIG_TOKEN, connectionManager_1.AmqpConnectionManager],
},
rabbitmq_factory_1.RabbitRpcParamsFactory,
],
exports: [connectionManager_1.AmqpConnectionManager, connection_1.AmqpConnection],
}),
__param(4, (0, rabbitmq_decorators_1.InjectRabbitMQConfig)()),
__metadata("design:paramtypes", [nestjs_discovery_1.DiscoveryService,
external_context_creator_1.ExternalContextCreator,
rabbitmq_factory_1.RabbitRpcParamsFactory,
connectionManager_1.AmqpConnectionManager, Object])
], RabbitMQModule);
exports.RabbitMQModule = RabbitMQModule;
//# sourceMappingURL=rabbitmq.module.js.map