rabbitmq-sdk 0.0.1-security → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rabbitmq-sdk might be problematic. Click here for more details.

Files changed (140) hide show
  1. package/.eslintrc.js +23 -0
  2. package/.kiro/specs/sdk-rabbitmq/design.md +369 -0
  3. package/.kiro/specs/sdk-rabbitmq/requirements.md +97 -0
  4. package/.kiro/specs/sdk-rabbitmq/tasks.md +248 -0
  5. package/README.md +273 -5
  6. package/bun.lock +790 -0
  7. package/config.example.json +13 -0
  8. package/dist/components/ConfigurationManager.d.ts +35 -0
  9. package/dist/components/ConfigurationManager.d.ts.map +1 -0
  10. package/dist/components/ConfigurationManager.js +118 -0
  11. package/dist/components/ConfigurationManager.js.map +1 -0
  12. package/dist/components/ConnectionManager.d.ts +93 -0
  13. package/dist/components/ConnectionManager.d.ts.map +1 -0
  14. package/dist/components/ConnectionManager.js +349 -0
  15. package/dist/components/ConnectionManager.js.map +1 -0
  16. package/dist/components/DLQHandler.d.ts +81 -0
  17. package/dist/components/DLQHandler.d.ts.map +1 -0
  18. package/dist/components/DLQHandler.js +228 -0
  19. package/dist/components/DLQHandler.js.map +1 -0
  20. package/dist/components/Logger.d.ts +77 -0
  21. package/dist/components/Logger.d.ts.map +1 -0
  22. package/dist/components/Logger.js +193 -0
  23. package/dist/components/Logger.js.map +1 -0
  24. package/dist/components/MessagePublisher.d.ts +49 -0
  25. package/dist/components/MessagePublisher.d.ts.map +1 -0
  26. package/dist/components/MessagePublisher.js +158 -0
  27. package/dist/components/MessagePublisher.js.map +1 -0
  28. package/dist/components/MessageSubscriber.d.ts +108 -0
  29. package/dist/components/MessageSubscriber.d.ts.map +1 -0
  30. package/dist/components/MessageSubscriber.js +503 -0
  31. package/dist/components/MessageSubscriber.js.map +1 -0
  32. package/dist/components/ResourceCreator.d.ts +89 -0
  33. package/dist/components/ResourceCreator.d.ts.map +1 -0
  34. package/dist/components/ResourceCreator.js +352 -0
  35. package/dist/components/ResourceCreator.js.map +1 -0
  36. package/dist/components/SdkRabbitmq.d.ts +103 -0
  37. package/dist/components/SdkRabbitmq.d.ts.map +1 -0
  38. package/dist/components/SdkRabbitmq.js +364 -0
  39. package/dist/components/SdkRabbitmq.js.map +1 -0
  40. package/dist/components/index.d.ts +9 -0
  41. package/dist/components/index.d.ts.map +1 -0
  42. package/dist/components/index.js +20 -0
  43. package/dist/components/index.js.map +1 -0
  44. package/dist/index.d.ts +5 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +27 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/interfaces/IConfiguration.d.ts +35 -0
  49. package/dist/interfaces/IConfiguration.d.ts.map +1 -0
  50. package/dist/interfaces/IConfiguration.js +3 -0
  51. package/dist/interfaces/IConfiguration.js.map +1 -0
  52. package/dist/interfaces/IConnection.d.ts +21 -0
  53. package/dist/interfaces/IConnection.d.ts.map +1 -0
  54. package/dist/interfaces/IConnection.js +3 -0
  55. package/dist/interfaces/IConnection.js.map +1 -0
  56. package/dist/interfaces/IDLQ.d.ts +12 -0
  57. package/dist/interfaces/IDLQ.d.ts.map +1 -0
  58. package/dist/interfaces/IDLQ.js +3 -0
  59. package/dist/interfaces/IDLQ.js.map +1 -0
  60. package/dist/interfaces/IErrors.d.ts +33 -0
  61. package/dist/interfaces/IErrors.d.ts.map +1 -0
  62. package/dist/interfaces/IErrors.js +56 -0
  63. package/dist/interfaces/IErrors.js.map +1 -0
  64. package/dist/interfaces/ILogger.d.ts +14 -0
  65. package/dist/interfaces/ILogger.d.ts.map +1 -0
  66. package/dist/interfaces/ILogger.js +3 -0
  67. package/dist/interfaces/ILogger.js.map +1 -0
  68. package/dist/interfaces/IMessage.d.ts +52 -0
  69. package/dist/interfaces/IMessage.d.ts.map +1 -0
  70. package/dist/interfaces/IMessage.js +3 -0
  71. package/dist/interfaces/IMessage.js.map +1 -0
  72. package/dist/interfaces/IResource.d.ts +31 -0
  73. package/dist/interfaces/IResource.d.ts.map +1 -0
  74. package/dist/interfaces/IResource.js +3 -0
  75. package/dist/interfaces/IResource.js.map +1 -0
  76. package/dist/interfaces/ISdkRabbitmq.d.ts +17 -0
  77. package/dist/interfaces/ISdkRabbitmq.d.ts.map +1 -0
  78. package/dist/interfaces/ISdkRabbitmq.js +3 -0
  79. package/dist/interfaces/ISdkRabbitmq.js.map +1 -0
  80. package/dist/interfaces/index.d.ts +9 -0
  81. package/dist/interfaces/index.d.ts.map +1 -0
  82. package/dist/interfaces/index.js +33 -0
  83. package/dist/interfaces/index.js.map +1 -0
  84. package/dist/utils/configSchema.d.ts +8 -0
  85. package/dist/utils/configSchema.d.ts.map +1 -0
  86. package/dist/utils/configSchema.js +51 -0
  87. package/dist/utils/configSchema.js.map +1 -0
  88. package/docker-compose.yml +24 -0
  89. package/example.ts +65 -0
  90. package/examples/README-dynamic-routing.md +155 -0
  91. package/examples/bind-unbind-example.js +56 -0
  92. package/examples/test-chatbot-exchange.ts +83 -0
  93. package/examples/test-dynamic-routing-flow.js +299 -0
  94. package/examples/test-dynamic-routing-flow.ts +355 -0
  95. package/examples/test-no-disconnect.ts +0 -0
  96. package/examples/test-raw-rabbitmq.js +68 -0
  97. package/examples/test-same-channel.ts +81 -0
  98. package/examples/test-schedule-flow.ts +713 -0
  99. package/examples/test-simple-greeting.ts +66 -0
  100. package/examples/test-simple-schedule.ts +76 -0
  101. package/examples/test-wildcard.ts +364 -0
  102. package/jest.config.js +17 -0
  103. package/package.json +42 -4
  104. package/preinstall.js +1 -0
  105. package/prompts/test-dynamic-routing-flow.md +46 -0
  106. package/run.js +4 -0
  107. package/scripts/run-dynamic-routing-test.ts +31 -0
  108. package/src/.gitkeep +1 -0
  109. package/src/components/.gitkeep +1 -0
  110. package/src/components/ConfigurationManager.ts +104 -0
  111. package/src/components/ConnectionManager.ts +357 -0
  112. package/src/components/DLQHandler.ts +271 -0
  113. package/src/components/Logger.ts +224 -0
  114. package/src/components/MessagePublisher.ts +180 -0
  115. package/src/components/MessageSubscriber.ts +597 -0
  116. package/src/components/ResourceCreator.ts +411 -0
  117. package/src/components/SdkRabbitmq.ts +443 -0
  118. package/src/components/__tests__/ConfigurationManager.test.ts +357 -0
  119. package/src/components/__tests__/ConnectionManager.test.ts +387 -0
  120. package/src/components/__tests__/DLQHandler.test.ts +399 -0
  121. package/src/components/__tests__/Logger.test.ts +354 -0
  122. package/src/components/__tests__/MessagePublisher.test.ts +337 -0
  123. package/src/components/__tests__/MessageSubscriber.test.ts +542 -0
  124. package/src/components/__tests__/ResourceCreator.test.ts +465 -0
  125. package/src/components/__tests__/SdkRabbitmq.integration.test.ts +433 -0
  126. package/src/components/index.ts +8 -0
  127. package/src/index.ts +11 -0
  128. package/src/interfaces/.gitkeep +1 -0
  129. package/src/interfaces/IConfiguration.ts +38 -0
  130. package/src/interfaces/IConnection.ts +27 -0
  131. package/src/interfaces/IDLQ.ts +13 -0
  132. package/src/interfaces/IErrors.ts +53 -0
  133. package/src/interfaces/ILogger.ts +16 -0
  134. package/src/interfaces/IMessage.ts +65 -0
  135. package/src/interfaces/IResource.ts +35 -0
  136. package/src/interfaces/ISdkRabbitmq.ts +26 -0
  137. package/src/interfaces/index.ts +23 -0
  138. package/src/utils/.gitkeep +1 -0
  139. package/src/utils/configSchema.ts +58 -0
  140. package/tsconfig.json +34 -0
@@ -0,0 +1,503 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MessageSubscriber = void 0;
4
+ const IErrors_1 = require("../interfaces/IErrors");
5
+ const Logger_1 = require("./Logger");
6
+ /**
7
+ * MessageSubscriber handles message consumption from RabbitMQ queues
8
+ * Implements parameter validation, JSON deserialization, automatic resource creation, and DLQ handling
9
+ */
10
+ class MessageSubscriber {
11
+ constructor(connectionManager, resourceCreator, dlqHandler, config) {
12
+ this.activeConsumers = new Map();
13
+ this.connectionManager = connectionManager;
14
+ this.resourceCreator = resourceCreator;
15
+ this.dlqHandler = dlqHandler;
16
+ this.logger = Logger_1.Logger.createComponentLogger('MessageSubscriber', config);
17
+ }
18
+ /**
19
+ * Subscribe to messages from a queue
20
+ * @param exchange Exchange name (required)
21
+ * @param queue Queue name (required)
22
+ * @param routingKey Routing key for binding (required)
23
+ * @param callback Message callback function (required)
24
+ */
25
+ async subscribe(exchange, queue, routingKey, callback) {
26
+ // Parameter validation - all parameters are required
27
+ this.validateSubscribeParameters(exchange, queue, routingKey, callback);
28
+ try {
29
+ // Automatic exchange and queue creation before subscribing
30
+ await this.ensureResourcesExist(exchange, queue, routingKey);
31
+ await this.connectionManager.executeOperation(async () => {
32
+ const connection = this.connectionManager.getConnection();
33
+ if (!connection) {
34
+ throw new IErrors_1.SubscriptionError('No active connection to RabbitMQ', {
35
+ exchange,
36
+ queue,
37
+ routingKey
38
+ });
39
+ }
40
+ // Create a dedicated channel for this consumer
41
+ const channel = await connection.createChannel();
42
+ try {
43
+ // Set prefetch to 1 for fair dispatch
44
+ await channel.prefetch(1);
45
+ // Start consuming messages
46
+ this.logger.info('🎯 SETTING UP CONSUMER', {
47
+ queue,
48
+ exchange,
49
+ routingKey
50
+ });
51
+ const consumerInfo = await channel.consume(queue, (message) => {
52
+ this.logger.info('📥 RAW MESSAGE RECEIVED', {
53
+ hasMessage: !!message,
54
+ queue,
55
+ exchange,
56
+ routingKey
57
+ });
58
+ if (message) {
59
+ this.logger.info('📋 MESSAGE DETAILS', {
60
+ exchange: message.fields.exchange,
61
+ routingKey: message.fields.routingKey,
62
+ deliveryTag: message.fields.deliveryTag,
63
+ contentLength: message.content.length
64
+ });
65
+ // Add queue name to message headers for DLQ handling
66
+ if (!message.properties.headers) {
67
+ message.properties.headers = {};
68
+ }
69
+ message.properties.headers['x-original-queue'] = queue;
70
+ this.handleMessage(message, callback, channel);
71
+ }
72
+ else {
73
+ this.logger.warn('⚠️ RECEIVED NULL MESSAGE', { queue });
74
+ }
75
+ }, {
76
+ noAck: false // We want manual acknowledgment
77
+ });
78
+ this.logger.info('✅ CONSUMER SETUP COMPLETE', {
79
+ consumerTag: consumerInfo.consumerTag,
80
+ queue
81
+ });
82
+ // Store consumer info for cleanup
83
+ this.activeConsumers.set(queue, {
84
+ channel,
85
+ consumerTag: consumerInfo.consumerTag
86
+ });
87
+ this.logger.logOperation('subscribe', `Successfully subscribed to queue`, {
88
+ queue,
89
+ exchange,
90
+ routingKey
91
+ });
92
+ }
93
+ catch (error) {
94
+ // Close channel on error
95
+ this.logger.logError('❌ ERROR DURING CONSUMER SETUP - CLOSING CHANNEL', error, {
96
+ queue,
97
+ exchange,
98
+ routingKey
99
+ });
100
+ await channel.close();
101
+ throw error;
102
+ }
103
+ });
104
+ }
105
+ catch (error) {
106
+ // Detailed error logging with context
107
+ this.logSubscriptionError(error, exchange, queue, routingKey);
108
+ throw error;
109
+ }
110
+ }
111
+ /**
112
+ * Unsubscribe from a queue
113
+ * @param queue Queue name to unsubscribe from
114
+ */
115
+ async unsubscribe(queue) {
116
+ if (!queue || typeof queue !== 'string') {
117
+ throw new IErrors_1.SubscriptionError('Queue parameter is required and must be a non-empty string', {
118
+ queue
119
+ });
120
+ }
121
+ const consumerInfo = this.activeConsumers.get(queue);
122
+ if (!consumerInfo) {
123
+ this.logger.warn(`No active subscription found for queue`, { queue });
124
+ return;
125
+ }
126
+ try {
127
+ // Cancel the consumer
128
+ await consumerInfo.channel.cancel(consumerInfo.consumerTag);
129
+ // Close the channel
130
+ await consumerInfo.channel.close();
131
+ // Remove from active consumers
132
+ this.activeConsumers.delete(queue);
133
+ this.logger.logOperation('unsubscribe', `Successfully unsubscribed from queue`, { queue });
134
+ }
135
+ catch (error) {
136
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
137
+ this.logger.logError(`Error unsubscribing from queue`, error, { queue });
138
+ // Still remove from active consumers even if cleanup failed
139
+ this.activeConsumers.delete(queue);
140
+ throw new IErrors_1.SubscriptionError(`Failed to unsubscribe from queue '${queue}'`, {
141
+ queue,
142
+ error: errorMessage
143
+ });
144
+ }
145
+ }
146
+ /**
147
+ * Handle incoming message
148
+ * @param message RabbitMQ message
149
+ * @param callback User callback function
150
+ * @param channel Channel for acknowledgment
151
+ */
152
+ handleMessage(message, callback, channel) {
153
+ const queueName = this.getQueueNameFromMessage(message);
154
+ // Debug log to see if messages are arriving
155
+ this.logger.info('🔥 MESSAGE RECEIVED IN HANDLER', {
156
+ exchange: message.fields.exchange,
157
+ routingKey: message.fields.routingKey,
158
+ queue: queueName,
159
+ deliveryTag: message.fields.deliveryTag
160
+ });
161
+ try {
162
+ // JSON deserialization for incoming messages
163
+ const deserializedPayload = this.deserializeMessage(message);
164
+ // Create ack/nack functions for callback
165
+ const ack = () => {
166
+ try {
167
+ channel.ack(message);
168
+ }
169
+ catch (error) {
170
+ this.logger.logError('Error acknowledging message', error, {
171
+ deliveryTag: message.fields.deliveryTag,
172
+ queue: queueName
173
+ });
174
+ }
175
+ };
176
+ const nack = async () => {
177
+ try {
178
+ await this.handleFailedMessage(message, queueName, channel);
179
+ }
180
+ catch (error) {
181
+ this.logger.logError('Error handling failed message', error, {
182
+ deliveryTag: message.fields.deliveryTag,
183
+ queue: queueName
184
+ });
185
+ // Fallback to regular nack with requeue
186
+ try {
187
+ channel.nack(message, false, true);
188
+ }
189
+ catch (nackError) {
190
+ this.logger.logError('Error negative acknowledging message', nackError, {
191
+ deliveryTag: message.fields.deliveryTag,
192
+ queue: queueName
193
+ });
194
+ }
195
+ }
196
+ };
197
+ // Debug log before invoking callback
198
+ this.logger.info('🚀 INVOKING USER CALLBACK', {
199
+ payloadType: typeof deserializedPayload,
200
+ queue: queueName
201
+ });
202
+ // Invoke callback with deserialized payload and ack/nack functions
203
+ callback(deserializedPayload, ack, nack);
204
+ this.logger.info('✅ USER CALLBACK COMPLETED', {
205
+ queue: queueName
206
+ });
207
+ }
208
+ catch (error) {
209
+ this.logger.logError('Error handling message', error, {
210
+ exchange: message.fields.exchange,
211
+ routingKey: message.fields.routingKey,
212
+ deliveryTag: message.fields.deliveryTag,
213
+ queue: queueName
214
+ });
215
+ // Handle deserialization or other processing errors
216
+ this.handleFailedMessage(message, queueName, channel).catch(dlqError => {
217
+ this.logger.logError('Error routing failed message to DLQ', dlqError, {
218
+ deliveryTag: message.fields.deliveryTag,
219
+ queue: queueName
220
+ });
221
+ // Fallback to regular nack without requeue to avoid infinite loop
222
+ try {
223
+ channel.nack(message, false, false);
224
+ }
225
+ catch (nackError) {
226
+ this.logger.logError('Error negative acknowledging failed message', nackError, {
227
+ deliveryTag: message.fields.deliveryTag,
228
+ queue: queueName
229
+ });
230
+ }
231
+ });
232
+ }
233
+ }
234
+ /**
235
+ * Validate subscribe method parameters
236
+ * @param exchange Exchange name
237
+ * @param queue Queue name
238
+ * @param routingKey Routing key
239
+ * @param callback Message callback function
240
+ */
241
+ validateSubscribeParameters(exchange, queue, routingKey, callback) {
242
+ if (!exchange || typeof exchange !== 'string') {
243
+ throw new IErrors_1.SubscriptionError('Exchange parameter is required and must be a non-empty string', {
244
+ exchange,
245
+ queue,
246
+ routingKey
247
+ });
248
+ }
249
+ if (!queue || typeof queue !== 'string') {
250
+ throw new IErrors_1.SubscriptionError('Queue parameter is required and must be a non-empty string', {
251
+ exchange,
252
+ queue,
253
+ routingKey
254
+ });
255
+ }
256
+ if (!routingKey || typeof routingKey !== 'string') {
257
+ throw new IErrors_1.SubscriptionError('RoutingKey parameter is required and must be a non-empty string', {
258
+ exchange,
259
+ queue,
260
+ routingKey
261
+ });
262
+ }
263
+ if (!callback || typeof callback !== 'function') {
264
+ throw new IErrors_1.SubscriptionError('Callback parameter is required and must be a function', {
265
+ exchange,
266
+ queue,
267
+ routingKey,
268
+ callbackType: typeof callback
269
+ });
270
+ }
271
+ }
272
+ /**
273
+ * Deserialize message content from JSON
274
+ * @param message RabbitMQ message
275
+ * @returns Deserialized payload
276
+ */
277
+ deserializeMessage(message) {
278
+ try {
279
+ const contentString = message.content.toString('utf8');
280
+ return JSON.parse(contentString);
281
+ }
282
+ catch (error) {
283
+ throw new IErrors_1.SubscriptionError('Failed to deserialize message content from JSON', {
284
+ contentType: message.properties.contentType,
285
+ contentLength: message.content.length,
286
+ error: error instanceof Error ? error.message : 'Unknown deserialization error'
287
+ });
288
+ }
289
+ }
290
+ /**
291
+ * Ensure exchange, queue, and binding exist before subscribing
292
+ * @param exchange Exchange name
293
+ * @param queue Queue name
294
+ * @param routingKey Routing key for binding
295
+ */
296
+ async ensureResourcesExist(exchange, queue, routingKey) {
297
+ try {
298
+ // Create exchange if it doesn't exist
299
+ // Always use topic type by default
300
+ await this.resourceCreator.ensureExchange(exchange, 'topic');
301
+ // Create queue if it doesn't exist
302
+ await this.resourceCreator.ensureQueue(queue);
303
+ // Bind queue to exchange with routing key
304
+ await this.resourceCreator.bindQueue(queue, exchange, routingKey);
305
+ }
306
+ catch (error) {
307
+ throw new IErrors_1.SubscriptionError('Failed to ensure resources exist for subscription', {
308
+ exchange,
309
+ queue,
310
+ routingKey,
311
+ error: error instanceof Error ? error.message : 'Unknown error'
312
+ });
313
+ }
314
+ }
315
+ /**
316
+ * Log subscription errors with detailed context
317
+ * @param error The error that occurred
318
+ * @param exchange Exchange name
319
+ * @param queue Queue name
320
+ * @param routingKey Routing key
321
+ */
322
+ logSubscriptionError(error, exchange, queue, routingKey) {
323
+ this.logger.logError('Message subscription failed', error, {
324
+ exchange,
325
+ queue,
326
+ routingKey,
327
+ operation: 'subscribe'
328
+ });
329
+ }
330
+ /**
331
+ * Get active consumer information for monitoring
332
+ */
333
+ getActiveConsumers() {
334
+ return Array.from(this.activeConsumers.keys());
335
+ }
336
+ /**
337
+ * Handle failed message by routing to DLQ or acknowledging based on configuration
338
+ * @param message Failed RabbitMQ message
339
+ * @param queueName Original queue name
340
+ * @param channel Channel for acknowledgment
341
+ */
342
+ async handleFailedMessage(message, queueName, channel) {
343
+ try {
344
+ if (this.dlqHandler.isEnabled()) {
345
+ // Check retry count to determine if message should go to DLQ
346
+ const retryCount = this.getRetryCount(message);
347
+ const maxRetries = this.dlqHandler.getDLQConfig().maxRetries || 3;
348
+ if (retryCount >= maxRetries) {
349
+ // Route to DLQ after max retries exceeded
350
+ await this.dlqHandler.handleFailedMessage(message, queueName);
351
+ // Acknowledge the message since it's been routed to DLQ
352
+ channel.ack(message);
353
+ this.logger.info(`Message routed to DLQ after retries`, {
354
+ retryCount,
355
+ queue: queueName,
356
+ deliveryTag: message.fields.deliveryTag
357
+ });
358
+ }
359
+ else {
360
+ // Increment retry count and requeue for retry
361
+ await this.requeueWithRetryCount(message, channel, retryCount + 1);
362
+ this.logger.info(`Message requeued for retry`, {
363
+ retryAttempt: retryCount + 1,
364
+ maxRetries,
365
+ queue: queueName,
366
+ deliveryTag: message.fields.deliveryTag
367
+ });
368
+ }
369
+ }
370
+ else {
371
+ // DLQ is disabled, acknowledge failed messages without reprocessing
372
+ channel.ack(message);
373
+ this.logger.info(`DLQ disabled. Failed message acknowledged without reprocessing`, {
374
+ queue: queueName,
375
+ deliveryTag: message.fields.deliveryTag
376
+ });
377
+ }
378
+ }
379
+ catch (error) {
380
+ this.logger.logError(`Failed to handle failed message`, error, {
381
+ queue: queueName,
382
+ deliveryTag: message.fields.deliveryTag
383
+ });
384
+ throw error;
385
+ }
386
+ }
387
+ /**
388
+ * Get retry count from message headers
389
+ * @param message RabbitMQ message
390
+ * @returns Current retry count
391
+ */
392
+ getRetryCount(message) {
393
+ if (!message.properties.headers) {
394
+ return 0;
395
+ }
396
+ return message.properties.headers['x-retry-count'] || 0;
397
+ }
398
+ /**
399
+ * Requeue message with incremented retry count
400
+ * @param message Original message
401
+ * @param channel Channel for operations
402
+ * @param retryCount New retry count
403
+ */
404
+ async requeueWithRetryCount(message, channel, retryCount) {
405
+ try {
406
+ // Add retry delay if configured
407
+ const retryDelay = this.dlqHandler.getDLQConfig().retryDelay || 0;
408
+ if (retryDelay > 0) {
409
+ // Use setTimeout for delay before requeuing
410
+ setTimeout(() => {
411
+ this.republishWithRetryCount(message, channel, retryCount).catch(error => {
412
+ this.logger.logError('Error republishing message with retry count', error, {
413
+ retryCount,
414
+ deliveryTag: message.fields.deliveryTag
415
+ });
416
+ // Fallback to regular nack
417
+ try {
418
+ channel.nack(message, false, true);
419
+ }
420
+ catch (nackError) {
421
+ this.logger.logError('Error negative acknowledging message', nackError, {
422
+ deliveryTag: message.fields.deliveryTag
423
+ });
424
+ }
425
+ });
426
+ }, retryDelay);
427
+ // Acknowledge original message since we're republishing
428
+ channel.ack(message);
429
+ }
430
+ else {
431
+ // No delay, just nack with requeue
432
+ channel.nack(message, false, true);
433
+ }
434
+ }
435
+ catch (error) {
436
+ this.logger.logError('Error requeuing message with retry count', error, {
437
+ retryCount,
438
+ deliveryTag: message.fields.deliveryTag
439
+ });
440
+ // Fallback to regular nack
441
+ channel.nack(message, false, true);
442
+ }
443
+ }
444
+ /**
445
+ * Republish message with updated retry count
446
+ * @param message Original message
447
+ * @param channel Channel for operations
448
+ * @param retryCount New retry count
449
+ */
450
+ async republishWithRetryCount(message, channel, retryCount) {
451
+ try {
452
+ // Update headers with retry count
453
+ const updatedHeaders = {
454
+ ...message.properties.headers,
455
+ 'x-retry-count': retryCount,
456
+ 'x-retry-timestamp': Date.now()
457
+ };
458
+ const publishOptions = {
459
+ ...message.properties,
460
+ headers: updatedHeaders
461
+ };
462
+ // Republish to the same exchange and routing key
463
+ const published = channel.publish(message.fields.exchange, message.fields.routingKey, message.content, publishOptions);
464
+ if (!published) {
465
+ throw new Error('Failed to republish message - channel buffer full');
466
+ }
467
+ }
468
+ catch (error) {
469
+ const errorMessage = `Failed to republish message with retry count: ${error instanceof Error ? error.message : 'Unknown error'}`;
470
+ throw new Error(errorMessage);
471
+ }
472
+ }
473
+ /**
474
+ * Extract queue name from message (fallback to routing key if not available)
475
+ * @param message RabbitMQ message
476
+ * @returns Queue name
477
+ */
478
+ getQueueNameFromMessage(message) {
479
+ // Try to get queue name from headers first
480
+ if (message.properties.headers && message.properties.headers['x-original-queue']) {
481
+ return message.properties.headers['x-original-queue'];
482
+ }
483
+ // Fallback to routing key (common pattern)
484
+ return message.fields.routingKey || 'unknown-queue';
485
+ }
486
+ /**
487
+ * Cleanup all active consumers (useful for shutdown)
488
+ */
489
+ async cleanup() {
490
+ const queues = Array.from(this.activeConsumers.keys());
491
+ for (const queue of queues) {
492
+ try {
493
+ await this.unsubscribe(queue);
494
+ }
495
+ catch (error) {
496
+ this.logger.logError(`Error cleaning up consumer for queue`, error, { queue });
497
+ }
498
+ }
499
+ this.logger.info('MessageSubscriber cleanup completed', { cleanedQueues: queues.length });
500
+ }
501
+ }
502
+ exports.MessageSubscriber = MessageSubscriber;
503
+ //# sourceMappingURL=MessageSubscriber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageSubscriber.js","sourceRoot":"","sources":["../../src/components/MessageSubscriber.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ import { IResourceCreator, QueueOptions, ExchangeOptions } from '../interfaces/IResource';
2
+ import { ConnectionManager } from './ConnectionManager';
3
+ import { IConfiguration } from '../interfaces/IConfiguration';
4
+ /**
5
+ * ResourceCreator handles automatic creation of exchanges, queues, and bindings
6
+ * Implements caching and existence checking to avoid duplicate creation attempts
7
+ */
8
+ export declare class ResourceCreator implements IResourceCreator {
9
+ private connectionManager;
10
+ private createdExchanges;
11
+ private createdQueues;
12
+ private createdBindings;
13
+ private existingExchanges;
14
+ private existingQueues;
15
+ private logger;
16
+ constructor(connectionManager: ConnectionManager, config?: IConfiguration['logging']);
17
+ /**
18
+ * Check if exchange exists without creating it
19
+ * @param exchange Exchange name
20
+ * @returns Promise<boolean> indicating if exchange exists
21
+ */
22
+ private checkExchangeExists;
23
+ /**
24
+ * Check if queue exists without creating it
25
+ * @param queue Queue name
26
+ * @returns Promise<boolean> indicating if queue exists
27
+ */
28
+ private checkQueueExists;
29
+ /**
30
+ * Ensure exchange exists, create if it doesn't
31
+ * @param exchange Exchange name
32
+ * @param type Exchange type (default: 'direct')
33
+ * @param options Exchange options
34
+ */
35
+ ensureExchange(exchange: string, type?: string, options?: ExchangeOptions): Promise<void>;
36
+ /**
37
+ * Ensure queue exists, create if it doesn't
38
+ * @param queue Queue name
39
+ * @param options Queue options
40
+ */
41
+ ensureQueue(queue: string, options?: QueueOptions): Promise<void>;
42
+ /**
43
+ * Bind queue to exchange with routing key
44
+ * @param queue Queue name
45
+ * @param exchange Exchange name
46
+ * @param routingKey Routing key for binding
47
+ */
48
+ bindQueue(queue: string, exchange: string, routingKey: string): Promise<void>;
49
+ /**
50
+ * Unbind queue from exchange with routing key
51
+ * @param queue Queue name
52
+ * @param exchange Exchange name
53
+ * @param routingKey Routing key for unbinding
54
+ */
55
+ unbindQueue(queue: string, exchange: string, routingKey: string): Promise<void>;
56
+ /**
57
+ * Clear all caches (useful for testing or reset scenarios)
58
+ */
59
+ clearCache(): void;
60
+ /**
61
+ * Get cache statistics for monitoring
62
+ */
63
+ getCacheStats(): {
64
+ created: {
65
+ exchanges: number;
66
+ queues: number;
67
+ bindings: number;
68
+ };
69
+ existing: {
70
+ exchanges: number;
71
+ queues: number;
72
+ };
73
+ };
74
+ /**
75
+ * Validate resource name format
76
+ * @param name Resource name to validate
77
+ * @param type Resource type for error messages
78
+ */
79
+ private validateResourceName;
80
+ /**
81
+ * Enhanced ensure exchange with validation
82
+ */
83
+ ensureExchangeWithValidation(exchange: string, type?: string, options?: ExchangeOptions): Promise<void>;
84
+ /**
85
+ * Enhanced ensure queue with validation
86
+ */
87
+ ensureQueueWithValidation(queue: string, options?: QueueOptions): Promise<void>;
88
+ }
89
+ //# sourceMappingURL=ResourceCreator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResourceCreator.d.ts","sourceRoot":"","sources":["../../src/components/ResourceCreator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D;;;GAGG;AACH,qBAAa,eAAgB,YAAW,gBAAgB;IACtD,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,iBAAiB,CAAqB;IAC9C,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,MAAM,CAAS;gBAEX,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC;IAKpF;;;;OAIG;YACW,mBAAmB;IA4BjC;;;;OAIG;YACW,gBAAgB;IA4B9B;;;;;OAKG;IACU,cAAc,CACzB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,MAAgB,EACtB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC;IA8DhB;;;;OAIG;IACU,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4DlF;;;;;OAKG;IACU,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiD1F;;;;;OAKG;IACU,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4C5F;;OAEG;IACI,UAAU,IAAI,IAAI;IASzB;;OAEG;IACI,aAAa,IAAI;QACtB,OAAO,EAAE;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;QACjE,QAAQ,EAAE;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KACjD;IAcD;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAgB5B;;OAEG;IACU,4BAA4B,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,MAAgB,EACtB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC;IAWhB;;OAEG;IACU,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;CAIjG"}