erp-plugin-sdk/src/backend/config/rabbitmq.config.ts

66 lines
2.0 KiB
TypeScript

import { Transport, MicroserviceOptions, RmqOptions } from '@nestjs/microservices';
import * as amqp from 'amqplib';
export const getRabbitMQOptions = (queueName: string, url?: string, pluginId?: string): MicroserviceOptions => {
const routingKeys: string[] = ['#'];
if (pluginId) {
routingKeys.push(`plugin.${pluginId}.*`);
}
return {
transport: Transport.RMQ,
options: {
urls: [url || process.env.RABBITMQ_URL || 'amqp://localhost:5672'],
queue: queueName,
exchange: 'system_events',
exchangeType: 'topic',
routingKey: routingKeys,
queueOptions: {
durable: true,
},
persistent: true,
noAck: true,
} as RmqOptions['options'] & { routingKey: string[] },
};
};
export const getRabbitMQClientOptions = (url?: string) => {
return {
transport: Transport.RMQ as const,
options: {
urls: [url || process.env.RABBITMQ_URL || 'amqp://localhost:5672'],
queue: 'core_queue',
exchange: 'system_events',
exchangeType: 'topic',
queueOptions: {
durable: true,
},
},
};
};
/**
* Bind a queue to the system_events exchange with the given routing keys.
* NestJS 10's ServerRMQ does not automatically bind queues to exchanges,
* so this must be called after app.startAllMicroservices().
* NestJS 11+ handles this automatically via the exchange/routingKey options.
*/
export async function setupQueueBindings(
queueName: string,
routingKeys: string[],
url?: string,
): Promise<void> {
const rmqUrl = url || process.env.RABBITMQ_URL || 'amqp://localhost:5672';
const conn = await amqp.connect(rmqUrl);
try {
const channel = await conn.createChannel();
await channel.assertExchange('system_events', 'topic', { durable: true });
await channel.assertQueue(queueName, { durable: true });
for (const key of routingKeys) {
await channel.bindQueue(queueName, 'system_events', key);
}
await channel.close();
} finally {
await conn.close().catch(() => {});
}
}