@autofleet/rabbit 4.0.2 → 4.1.0-beta.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.
Files changed (57) hide show
  1. package/coverage/clover.xml +669 -0
  2. package/coverage/coverage-final.json +9 -0
  3. package/coverage/lcov-report/base.css +224 -0
  4. package/coverage/lcov-report/block-navigation.js +87 -0
  5. package/coverage/lcov-report/favicon.png +0 -0
  6. package/coverage/lcov-report/index.html +131 -0
  7. package/coverage/lcov-report/prettify.css +1 -0
  8. package/coverage/lcov-report/prettify.js +2 -0
  9. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  10. package/coverage/lcov-report/sorter.js +196 -0
  11. package/coverage/lcov-report/src/index.html +131 -0
  12. package/coverage/lcov-report/src/index.ts.html +3826 -0
  13. package/coverage/lcov-report/src/lib/celery.ts.html +352 -0
  14. package/coverage/lcov-report/src/lib/consts.ts.html +142 -0
  15. package/coverage/lcov-report/src/lib/index.html +191 -0
  16. package/coverage/lcov-report/src/lib/rabbitError.ts.html +103 -0
  17. package/coverage/lcov-report/src/lib/redis.ts.html +133 -0
  18. package/coverage/lcov-report/src/lib/types.ts.html +268 -0
  19. package/coverage/lcov-report/src/lib/utils.ts.html +142 -0
  20. package/coverage/lcov-report/src/logger.ts.html +100 -0
  21. package/coverage/lcov.info +1076 -0
  22. package/dist/index.d.ts +19 -33
  23. package/dist/index.js +217 -341
  24. package/dist/lib/celery.js +0 -1
  25. package/dist/lib/consts.d.ts +2 -10
  26. package/dist/lib/consts.js +3 -12
  27. package/dist/lib/rabbitError.js +0 -1
  28. package/dist/lib/redis.js +0 -1
  29. package/dist/lib/types.d.ts +0 -8
  30. package/dist/lib/types.js +0 -1
  31. package/dist/lib/utils.d.ts +0 -5
  32. package/dist/lib/utils.js +1 -9
  33. package/dist/logger.js +0 -1
  34. package/dist/{mock/index.d.ts → mock.d.ts} +1 -1
  35. package/dist/{mock/index.js → mock.js} +1 -2
  36. package/package.json +16 -23
  37. package/src/index.ts +243 -417
  38. package/src/lib/consts.ts +2 -11
  39. package/src/lib/types.ts +0 -10
  40. package/src/lib/utils.ts +0 -10
  41. package/src/{mock/index.ts → mock.ts} +2 -2
  42. package/tsconfig.json +2 -2
  43. package/dist/index.js.map +0 -1
  44. package/dist/lib/celery.js.map +0 -1
  45. package/dist/lib/consts.js.map +0 -1
  46. package/dist/lib/rabbitError.js.map +0 -1
  47. package/dist/lib/redis.js.map +0 -1
  48. package/dist/lib/types.js.map +0 -1
  49. package/dist/lib/utils.js.map +0 -1
  50. package/dist/logger.js.map +0 -1
  51. package/dist/mock/index.js.map +0 -1
  52. package/dist/mock/vitest.d.ts +0 -13
  53. package/dist/mock/vitest.js +0 -18
  54. package/dist/mock/vitest.js.map +0 -1
  55. package/src/mock/vitest.ts +0 -24
  56. package/tsconfig.build.json +0 -5
  57. package/vitest.config.ts +0 -17
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
- /* eslint-disable no-empty,consistent-return,no-async-promise-executor,@typescript-eslint/no-unused-vars,no-param-reassign */
1
+ /* eslint-disable no-empty,consistent-return,no-async-promise-executor,@typescript-eslint/no-unused-vars */
2
+
2
3
  import { EventEmitter, once } from 'events';
3
4
  import { promisify } from 'util';
4
5
  import moment from 'moment';
@@ -9,19 +10,19 @@ import {
9
10
  import {
10
11
  ConfirmChannel, ConsumeMessage, Options, Replies,
11
12
  } from 'amqplib';
12
- import { backOff } from 'exponential-backoff';
13
13
  import {
14
14
  getCurrentPayload, newTrace, traceTypes, createOrSetRabbitTrace, outbreak,
15
15
  } from '@autofleet/zehut';
16
16
  import { randomUUID } from 'node:crypto';
17
+ import axios from 'axios';
17
18
  import logger from './logger';
18
19
  import RabbitError from './lib/rabbitError';
19
20
  import getRedisInstance, { RedisConfig } from './lib/redis';
20
- import {
21
- assertExchangeFanout, getAssertVhostExponentialBackoffConfig, rand, wrapSetImmediate,
22
- } from './lib/utils';
21
+ import { assertExchangeFanout, rand, wrapSetImmediate } from './lib/utils';
23
22
  import {
24
23
  AUTOMATION_ID_HEADER,
24
+ CONNECTION_CREATED_CONST,
25
+ CONNECTION_FAILED_CONST,
25
26
  DEFAULT_LOCK_TIMEOUT,
26
27
  DEFAULT_OPTIONS,
27
28
  RETRY_HEADER,
@@ -40,7 +41,6 @@ import {
40
41
  CONSUMER_DEFAULT_OPTIONS,
41
42
  QueueSetupPromisesDictionary,
42
43
  AssertExchangePromisesDictionary,
43
- ConnectionData,
44
44
  } from './lib/types';
45
45
 
46
46
  // const debug = nodeDebug('af-rabbitmq')
@@ -48,12 +48,6 @@ const debug = logger.debug.bind(logger);
48
48
 
49
49
  const PUBLISH_TIMEOUT = 1000 * 10;
50
50
 
51
- // TODO: [QUORUM-PHASE-3] Delete this env var
52
- const {
53
- DISABLE_QUORUM_QUEUES_CONSUME,
54
- DISABLE_QUORUM_QUEUES_PUBLISH,
55
- } = process.env;
56
-
57
51
  export interface IAfRabbitMq {
58
52
  ack: any;
59
53
  nack: any;
@@ -95,13 +89,11 @@ type newChannelOpts = {
95
89
  name?: string;
96
90
  onClose?: null | ((args: any | null) => void);
97
91
  options?: CreateChannelOpts | undefined;
98
- connection: ConnectionData;
99
92
  };
100
93
 
101
94
  type assertChannelOpts = {
102
95
  channelName?: string;
103
96
  force?: boolean;
104
- connection: ConnectionData;
105
97
  }
106
98
 
107
99
  type AfConsumer = {
@@ -154,15 +146,13 @@ class RabbitMq implements IAfRabbitMq {
154
146
 
155
147
  RECONNECT_MSG = 'rabbit: connection disconnect - reconnecting';
156
148
 
157
- publishChannel: ChannelWrapper | null;
149
+ channel: ChannelWrapper | null;
158
150
 
159
151
  publishChannelSetupPromise: Promise<ChannelWrapper> | null;
160
152
 
161
153
  blockReconnect: boolean | null | undefined
162
154
 
163
- publishConnection: ConnectionData
164
-
165
- consumeConnection: ConnectionData
155
+ connection: AmqpConnectionManager | null | undefined
166
156
 
167
157
  em: EventEmitter;
168
158
 
@@ -176,33 +166,28 @@ class RabbitMq implements IAfRabbitMq {
176
166
 
177
167
  assertExchangePromises: AssertExchangePromisesDictionary;
178
168
 
179
- options: AfRabbitOptions;
169
+ options: AfRabbitOptions | undefined;
180
170
 
181
171
  redisClient: any;
182
172
 
183
173
  redisLock?: RedisLockType;
184
174
 
185
175
  /** Array of consumers tags used for canceling consumption */
186
- consumersTags: Map<string, { channel: ConfirmChannel; consumerTag: string }>;
176
+ consumersTags: Array<[ConfirmChannel, string]>;
187
177
 
188
- private consumersToRegister: Array<AfConsumer> = [];
178
+ private consumers: Array<AfConsumer> = [];
189
179
 
190
- private doesVHostExist = false;
180
+ private isVHostExist = false;
191
181
 
192
- private vhost = 'quorum-vhost';
182
+ // TODO: DELETE OLD PROPERTIES
193
183
 
194
- private gracefulShutdownStarted = false;
195
-
196
- // TODO:[QUORUM-PHASE-3] Delete the old properties that we use for the old consumers and publishers
197
- oldPublishChannel: ChannelWrapper | null;
184
+ oldChannel: ChannelWrapper | null;
198
185
 
199
186
  oldPublishChannelSetupPromise: Promise<ChannelWrapper> | null;
200
187
 
201
188
  oldBlockReconnect: boolean | null | undefined
202
189
 
203
- oldPublishConnection: ConnectionData
204
-
205
- oldConsumeConnection: ConnectionData
190
+ oldConnection: AmqpConnectionManager | null | undefined
206
191
 
207
192
  oldEm: EventEmitter;
208
193
 
@@ -216,41 +201,32 @@ class RabbitMq implements IAfRabbitMq {
216
201
 
217
202
  oldAssertExchangePromises: AssertExchangePromisesDictionary;
218
203
 
219
- oldConsumersTags: Map<string, { channel: ConfirmChannel; consumerTag: string }>;
204
+ oldConsumersTags: Array<[ConfirmChannel, string]>;
220
205
 
221
- private oldConsumersToRegister: Array<AfConsumer> = [];
206
+ private oldConsumers: Array<AfConsumer> = [];
222
207
 
223
208
  constructor(options: AfRabbitOptions = {}, redisConfig?: RedisConfig) {
224
209
  this.em = new EventEmitter();
225
- this.publishChannel = null;
210
+ this.channel = null;
226
211
  this.publishChannelSetupPromise = null;
227
- this.publishConnection = {
228
- amqpConnection: null,
229
- creatingConnection: false,
230
- connectionCreatedEventName: 'publishConnectionCreated',
231
- connectionFailedEventName: 'publishConnectionFailed',
232
- blockReconnect: false,
233
- };
234
- this.consumeConnection = {
235
- amqpConnection: null,
236
- creatingConnection: false,
237
- connectionCreatedEventName: 'consumeConnectionCreated',
238
- connectionFailedEventName: 'consumeConnectionFailed',
239
- blockReconnect: false,
240
- };
212
+ this.connection = null;
241
213
  this.creatingConnection = false;
242
214
  this.exchanges = {};
243
215
  this.queues = {};
244
216
  this.queueSetupPromises = {};
245
217
  this.assertExchangePromises = {};
246
- this.consumersToRegister = [];
218
+ this.consumers = [];
247
219
  this.options = options;
248
220
 
221
+ if (!options?.vhost) {
222
+ this.options.vhost = process.env.VHOST_NAME || 'quorum-vhost';
223
+ }
224
+
249
225
  this.redisClient = redisConfig && getRedisInstance(redisConfig);
250
226
  if (this.redisClient) {
251
227
  this.redisLock = promisify(RedisLock(this.redisClient)) as RedisLockType;
252
228
  }
253
- this.consumersTags = new Map<string, { channel: ConfirmChannel; consumerTag: string }>();
229
+ this.consumersTags = [];
254
230
  logger.info(`rabbit: [gracefully-shutdown] adding gracefully shutdown for process.pid ${process.pid}`);
255
231
  if (!this.options?.dontGracefulShutdown) {
256
232
  process.on('SIGTERM', async () => {
@@ -261,85 +237,72 @@ class RabbitMq implements IAfRabbitMq {
261
237
  });
262
238
  }
263
239
 
264
- // TODO: [QUORUM-PHASE-3] Delete the old properties that we use for the old consumers and publishers
240
+ // TODO: DELETE OLD PROPERTIES
265
241
  this.oldEm = new EventEmitter();
266
- this.oldPublishChannel = null;
242
+ this.oldChannel = null;
267
243
  this.oldPublishChannelSetupPromise = null;
268
- this.oldPublishConnection = {
269
- amqpConnection: null,
270
- creatingConnection: false,
271
- connectionCreatedEventName: 'oldPublishConnectionCreated',
272
- connectionFailedEventName: 'oldPublishConnectionFailed',
273
- blockReconnect: false,
274
- };
275
- this.oldConsumeConnection = {
276
- amqpConnection: null,
277
- creatingConnection: false,
278
- connectionCreatedEventName: 'oldConsumeConnectionCreated',
279
- connectionFailedEventName: 'oldConsumeConnectionFailed',
280
- blockReconnect: false,
281
- };
244
+ this.oldConnection = null;
282
245
  this.oldCreatingConnection = false;
283
246
  this.oldExchanges = {};
284
247
  this.oldQueues = {};
285
248
  this.oldQueueSetupPromises = {};
286
249
  this.oldAssertExchangePromises = {};
287
- this.oldConsumersToRegister = [];
288
- this.oldConsumersTags = new Map<string, { channel: ConfirmChannel; consumerTag: string }>();
250
+ this.oldConsumers = [];
251
+ this.oldConsumersTags = [];
289
252
  }
290
253
 
291
254
  private assertVHost = async () => {
292
- if (this.doesVHostExist) {
255
+ if (this.isVHostExist) {
293
256
  return;
294
257
  }
295
258
 
296
- const username = process.env.RABBITMQ_USERNAME || 'guest';
297
- const password = process.env.RABBITMQ_PASSWORD || 'guest';
298
- const credentials = Buffer.from(`${username}:${password}`).toString('base64');
299
- const headers = {
300
- Authorization: `Basic ${credentials}`,
301
- 'Content-Type': 'application/json',
302
- };
303
-
304
- const rabbitHost = `http://${(this.options?.rabbitHost || process.env.RABBITMQ_SERVICE_HOST || 'localhost').split(':')[0]}:15672`;
259
+ if (!this.options?.vhost) {
260
+ throw new Error('vhost is not defined');
261
+ }
305
262
 
306
- const url = `${rabbitHost}/api/vhosts/${encodeURIComponent(this.vhost)}`;
263
+ const { vhost } = this.options;
264
+ const auth = {
265
+ auth: {
266
+ username: process.env.RABBITMQ_USERNAME || 'guest',
267
+ password: process.env.RABBITMQ_PASSWORD || 'guest',
268
+ },
269
+ };
270
+ const rabbitHost = `http://${(this.options.rabbitHost || process.env.RABBITMQ_SERVICE_HOST || 'localhost').split(':')[0]}:15672`;
307
271
 
308
272
  try {
309
- const response = await fetch(url, {
310
- method: 'GET',
311
- headers,
312
- });
313
-
314
- if (response.status === 200) {
315
- this.doesVHostExist = true;
316
- logger.info('Vhost exists', { vhost: this.vhost });
317
- return;
318
- }
273
+ const response = await axios.get(`${rabbitHost}/api/vhosts/${encodeURIComponent(vhost)}`, auth);
319
274
 
320
- if (response.status !== 404) {
321
- logger.error('Failed to check vhost', { response });
322
- throw new RabbitError('Failed to check vhost');
275
+ if (response.status !== 200) {
276
+ throw new Error('Failed to check vhost');
323
277
  }
324
278
 
325
- const createResponse = await fetch(url, {
326
- method: 'PUT',
327
- headers,
328
- body: JSON.stringify({ default_queue_type: 'quorum' }),
329
- });
279
+ this.isVHostExist = true;
280
+ logger.info('Vhost exists', { vhost });
281
+ } catch (error) {
282
+ // If the vhost does not exist, create it
283
+ if (error instanceof axios.AxiosError && error.response?.status === 404) {
284
+ try {
285
+ await axios.put(
286
+ `${rabbitHost}/api/vhosts/${encodeURIComponent(vhost)}`,
287
+ {
288
+ default_queue_type: 'quorum',
289
+ },
290
+ auth,
291
+ );
330
292
 
331
- if (!createResponse.ok) {
332
- logger.error('Failed to create vhost', { response: createResponse });
333
- throw new RabbitError('Failed to create vhost');
293
+ this.isVHostExist = true;
294
+ logger.info('Vhost created', { vhost: this.options?.vhost });
295
+ return;
296
+ } catch (createError) {
297
+ logger.error('Failed to create vhost', { error: createError });
298
+ throw createError;
299
+ }
334
300
  }
335
301
 
336
- this.doesVHostExist = true;
337
- logger.info('Vhost created', { vhost: this.vhost });
338
- } catch (error) {
339
- logger.error('Failed to check or create vhost', { error });
302
+ logger.error('Failed to check vhost', { error });
340
303
  throw error;
341
304
  }
342
- };
305
+ }
343
306
 
344
307
  private shouldConsumeMessageByTimestamp = async (msg: ConsumeMessageOrNull) => {
345
308
  if (msg) {
@@ -388,13 +351,13 @@ class RabbitMq implements IAfRabbitMq {
388
351
  if (
389
352
  !skipRetry
390
353
  && (
391
- !msg.properties.headers?.[RETRY_HEADER]
354
+ !msg.properties.headers[RETRY_HEADER]
392
355
  || parseInt(msg.properties.headers[RETRY_HEADER], 10) < options.retries
393
356
  )
394
357
  ) {
395
358
  await this.sendToQueue(queue, RabbitMq.parseMsg(msg).content, options, {
396
359
  ...msg.properties.headers,
397
- [RETRY_HEADER]: msg.properties.headers?.[RETRY_HEADER]
360
+ [RETRY_HEADER]: msg.properties.headers[RETRY_HEADER]
398
361
  ? msg.properties.headers[RETRY_HEADER] + 1
399
362
  : 1,
400
363
  });
@@ -402,7 +365,7 @@ class RabbitMq implements IAfRabbitMq {
402
365
  const deadQueue = `${queue}-dead`;
403
366
  await this.sendToQueue(deadQueue, RabbitMq.parseMsg(msg).content, deadQueueOptions, {
404
367
  ...msg.properties.headers,
405
- [RETRY_HEADER]: msg.properties.headers?.[RETRY_HEADER]
368
+ [RETRY_HEADER]: msg.properties.headers[RETRY_HEADER]
406
369
  ? msg.properties.headers[RETRY_HEADER] + 1
407
370
  : 1,
408
371
  });
@@ -416,38 +379,30 @@ class RabbitMq implements IAfRabbitMq {
416
379
  }
417
380
  }
418
381
 
419
- async getConnection(connection: ConnectionData) {
382
+ async getConnection() {
420
383
  return new Promise<AmqpConnectionManager>(async (resolve, reject) => {
421
- const {
422
- amqpConnection: connectionLocal,
423
- creatingConnection,
424
- connectionCreatedEventName,
425
- connectionFailedEventName,
426
- blockReconnect,
427
- } = connection;
428
-
429
- if (blockReconnect) {
384
+ if (this.blockReconnect) {
430
385
  debug('rabbit: block reconnect');
431
386
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
432
387
  // @ts-ignore
433
388
  return resolve();
434
389
  }
435
- if (connectionLocal !== null) {
436
- if (this.options?.disableReconnect || connectionLocal?.isConnected()) {
390
+ if (this.connection !== null) {
391
+ if (this.options?.disableReconnect || this.connection?.isConnected()) {
437
392
  debug('rabbit: connection - is connected');
438
393
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
439
394
  // @ts-ignore
440
- return resolve(connectionLocal);
395
+ return resolve(this.connection);
441
396
  }
442
397
  debug('rabbit: connection - reconnecting');
443
398
  }
444
- if (creatingConnection) {
399
+ if (this.creatingConnection) {
445
400
  debug('rabbit: creating connection emi');
446
- this.em.once(connectionCreatedEventName, resolve);
447
- this.em.once(connectionFailedEventName, reject);
401
+ this.em.once(CONNECTION_CREATED_CONST, resolve);
402
+ this.em.once(CONNECTION_FAILED_CONST, reject);
448
403
  return;
449
404
  }
450
- connection.creatingConnection = true;
405
+ this.creatingConnection = true;
451
406
  let isResolved = false;
452
407
 
453
408
  // It is import to use it as a function and not as a variable
@@ -459,72 +414,65 @@ class RabbitMq implements IAfRabbitMq {
459
414
  const host = this.options?.rabbitHost || process.env.RABBITMQ_SERVICE_HOST || 'localhost';
460
415
 
461
416
  debug('rabbit: creating connection', { host, userName, HEARTBEAT });
462
- return [`amqp://${userName}:${password}@${host}/${this.vhost}?heartbeat=${HEARTBEAT}`];
417
+ return [`amqp://${userName}:${password}@${host}/${this.options?.vhost}?heartbeat=${HEARTBEAT}`];
463
418
  };
464
419
 
465
420
  const defaultUrls = findServers();
466
- const newConnection: AmqpConnectionManager = await connect(defaultUrls, {
421
+ const connection: AmqpConnectionManager = await connect(defaultUrls, {
467
422
  findServers,
468
423
  });
469
424
 
470
- connection.amqpConnection = newConnection;
471
- newConnection.on('error', (err) => {
425
+ this.connection = connection;
426
+ this.connection.on('error', (err) => {
472
427
  logger.error('rabbit: connection error', { err });
473
428
  if (!isResolved) {
474
429
  isResolved = true;
475
430
  reject(err);
476
- this.em.emit(connectionFailedEventName, err);
431
+ this.em.emit(CONNECTION_FAILED_CONST, err);
477
432
  }
478
433
  });
479
434
 
480
- newConnection.on('connectFailed', (err) => {
481
- this.consumersTags.clear();
482
- if (typeof err.url === 'string') {
483
- err.url = this.maskURL(err.url);
484
- }
485
- logger.error('rabbit: connection connectFailed', { err, advice: 'Check if the vhost exist', vhost: this.vhost });
435
+ this.connection.on('connectFailed', (err) => {
436
+ this.consumersTags = [];
437
+ logger.error('rabbit: connection connectFailed', { err, advice: 'Check if the vhost exist', vhost: this.options?.vhost });
486
438
  if (!isResolved) {
487
439
  isResolved = true;
488
440
  reject(err);
489
- this.em.emit(connectionFailedEventName, err);
441
+ this.em.emit(CONNECTION_FAILED_CONST, err);
490
442
  }
491
443
  });
492
444
 
493
- newConnection.on('disconnect', ({ err }) => {
494
- this.consumersTags.clear();
445
+ this.connection.on('disconnect', ({ err }) => {
446
+ // this.channel = null;
447
+ this.consumersTags = [];
495
448
  debug('rabbit: connection closed');
496
449
  if (this.options?.disableReconnect) {
497
450
  logger.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
498
- connection.blockReconnect = true;
451
+ this.blockReconnect = true;
499
452
  } else {
500
453
  logger.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
501
454
  }
502
455
  });
503
456
 
504
- newConnection.once('connect', async () => {
457
+ this.connection.once('connect', async () => {
505
458
  debug('rabbit: connection established');
506
- connection.creatingConnection = false;
507
- this.em.emit(connectionCreatedEventName, newConnection);
459
+ this.creatingConnection = false;
460
+ this.em.emit(CONNECTION_CREATED_CONST, connection);
508
461
  isResolved = true;
509
- resolve(newConnection);
462
+ resolve(connection);
510
463
  });
511
464
  });
512
465
  }
513
466
 
514
- async getNewChannel({
515
- name = rand().toString(),
516
- onClose = null,
517
- options = {},
518
- connection,
519
- }: newChannelOpts) {
520
- let localConnection!: AmqpConnectionManager;
467
+ async getNewChannel({ name = rand().toString(), onClose = null, options = {} }: newChannelOpts = {}) {
468
+ let connection!: AmqpConnectionManager;
521
469
  try {
522
- localConnection = await this.getConnection(connection);
470
+ connection = await this.getConnection();
523
471
  } catch (e) {
524
472
  logger.error(`rabbit: error on get connection for new channel ${name} `, { e });
525
473
  throw e;
526
474
  }
527
- const channel = localConnection?.createChannel({ ...options });
475
+ const channel = connection.createChannel({ ...options });
528
476
  once(channel, 'close').then((args) => {
529
477
  logger.error(`rabbit: channel ${name} closed`);
530
478
  onClose?.(args);
@@ -539,21 +487,19 @@ class RabbitMq implements IAfRabbitMq {
539
487
  }
540
488
  }
541
489
 
542
- async assertChannel({ force = false, connection }: assertChannelOpts): Promise<ChannelWrapper> {
490
+ async assertChannel({ force = false } : assertChannelOpts = {}): Promise<ChannelWrapper> {
543
491
  if (!this.publishChannelSetupPromise) {
544
492
  this.publishChannelSetupPromise = new Promise<ChannelWrapper>(async (resolve, reject) => {
545
- if (this.publishChannel && !force) {
546
- return resolve(this.publishChannel);
493
+ if (this.channel && !force) {
494
+ return resolve(this.channel);
547
495
  }
548
496
 
549
497
  try {
550
- const channel = await this.getNewChannel({ connection });
498
+ const channel = await this.getNewChannel({});
551
499
  channel.on('error', (err) => {
552
500
  logger.error('rabbit: channel error', { err });
553
501
  });
554
- if (this.publishConnection === connection) {
555
- this.publishChannel = channel;
556
- }
502
+ this.channel = channel;
557
503
  resolve(channel);
558
504
  } catch (e) {
559
505
  reject(e);
@@ -563,8 +509,8 @@ class RabbitMq implements IAfRabbitMq {
563
509
  return this.publishChannelSetupPromise;
564
510
  }
565
511
 
566
- async assertExchange(exchangeName: string, connection: ConnectionData) {
567
- const channel: ChannelWrapper = await this.assertChannel({ connection });
512
+ async assertExchange(exchangeName: string, options?: any) {
513
+ const channel: ChannelWrapper = await this.assertChannel();
568
514
 
569
515
  if (this.exchanges[exchangeName]) {
570
516
  delete this.assertExchangePromises[exchangeName];
@@ -582,17 +528,17 @@ class RabbitMq implements IAfRabbitMq {
582
528
 
583
529
  async getQueueLength(queue: string) {
584
530
  RabbitMq.validateName('queue', queue);
585
- const { publishChannel: channel } = this;
531
+ const { channel } = this;
586
532
  if (!channel) {
587
- throw new RabbitError('channel is not defined');
533
+ throw new Error('channel is not defined');
588
534
  }
589
- debug('rabbit: getting queue length', { queue, connected: this.publishConnection.amqpConnection?.isConnected() });
535
+ debug('rabbit: getting queue length', { queue, connected: this.connection?.isConnected() });
590
536
  return channel?.checkQueue(queue);
591
537
  }
592
538
 
593
- private async deleteQueue(queue: string, connection: ConnectionData) {
539
+ private async deleteQueue(queue: string) {
594
540
  RabbitMq.validateName('queue', queue);
595
- const channel: ChannelWrapper = await this.assertChannel({ connection });
541
+ const channel: ChannelWrapper = await this.assertChannel();
596
542
  logger.info('rabbit: deleting queue', { queue });
597
543
  const deleteQueueRes = await channel.deleteQueue(queue);
598
544
  debug('queue deleted', deleteQueueRes);
@@ -600,14 +546,13 @@ class RabbitMq implements IAfRabbitMq {
600
546
  }
601
547
 
602
548
  async bindQueue(queue: string, exchange: string) {
603
- const channel: ChannelWrapper = await this.assertChannel({ connection: this.publishConnection });
549
+ const channel: ChannelWrapper = await this.assertChannel();
604
550
  await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.bindQueue(queue, exchange, ''));
605
551
  return channel.bindQueue(queue, exchange, '');
606
552
  }
607
553
 
608
554
  async setupQueue(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue> {
609
555
  let queue: Replies.AssertQueue;
610
- const connection = this.publishConnection;
611
556
  const localeOptions = {
612
557
  ...options,
613
558
  durable: true,
@@ -618,7 +563,7 @@ class RabbitMq implements IAfRabbitMq {
618
563
  },
619
564
  };
620
565
  try {
621
- const channel: ChannelWrapper = await this.assertChannel({ connection });
566
+ const channel: ChannelWrapper = await this.assertChannel();
622
567
  debug('assertQueue->channel.addSetup', { queueName });
623
568
  await channel.addSetup(async (setupChannel: ConfirmChannel) => {
624
569
  await setupChannel.assertQueue(queueName, localeOptions);
@@ -629,8 +574,8 @@ class RabbitMq implements IAfRabbitMq {
629
574
  logger.error('rabbit: assertQueue error', { queueName, options, error: e });
630
575
  if (!this.options?.dontRetryAssert) {
631
576
  debug('retrying assertQueue', { queueName });
632
- const channel = await this.assertChannel({ force: true, connection });
633
- await this.deleteQueue(queueName, connection);
577
+ const channel = await this.assertChannel({ force: true });
578
+ await this.deleteQueue(queueName);
634
579
 
635
580
  debug('retrying assertQueue->channel.addSetup', { queueName });
636
581
  await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
@@ -645,7 +590,7 @@ class RabbitMq implements IAfRabbitMq {
645
590
  return queue;
646
591
  }
647
592
 
648
- // TODO: [QUORUM-PHASE-3] Can be deleted after deleting the old consumers and publishers because all the queues are created us quorum queues
593
+ // TODO: Can be deleted after deleting the old consumers
649
594
  static shouldUseQuorum(queueName: string): boolean {
650
595
  const envQuorumQueuesWhitelist = process.env.QUORUM_QUEUES_WHITELIST;
651
596
 
@@ -677,10 +622,10 @@ class RabbitMq implements IAfRabbitMq {
677
622
  }
678
623
 
679
624
  private saveConsumer(queue: string, callback: CallbackFunction, options: ConsumeOptions | undefined) {
680
- const isConsumerExist: boolean = this.consumersToRegister.some((consumer) => consumer.queue === queue);
625
+ const isConsumerExist :boolean = this.consumers.some((consumer) => consumer.queue === queue);
681
626
  if (!isConsumerExist) {
682
627
  logger.info(`rabbit: consumer: ${queue} saved in consumer array`);
683
- this.consumersToRegister.push({
628
+ this.consumers.push({
684
629
  queue,
685
630
  callback,
686
631
  options,
@@ -690,24 +635,21 @@ class RabbitMq implements IAfRabbitMq {
690
635
 
691
636
  // Used by the microservices to consume messages from the queue
692
637
  async consume(queue: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any> {
693
- this.saveConsumerOld(queue, callback, options);
694
-
695
- // TODO: [QUORUM-PHASE-3] Use only the implementation of consumeNew and delete consumeNew and consumeOld
696
- if (options?.isQuorumQueue !== false && DISABLE_QUORUM_QUEUES_CONSUME !== 'true') {
697
- this.saveConsumer(queue, callback, options);
698
- const backoffConfig = getAssertVhostExponentialBackoffConfig();
699
- await backOff(() => this.assertVHost(), backoffConfig);
638
+ // TODO: USE THE IMPLEMENTATION OF THE NEW CONSUME AND DELETE THE NEW AND OLD
639
+ if (options?.isQuorumQueue !== false) {
640
+ await this.assertVHost();
700
641
  await this.consumeNew(queue, callback, options);
701
642
  }
643
+
702
644
  await this.consumeOld(queue, callback, options);
703
645
  }
704
646
 
705
- // TODO: [QUORUM-PHASE-3] Delete consumeNew we do not use it anymore
647
+ // TODO: DELETE
706
648
  async consumeNew(queue: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any> {
707
649
  await this.consumeFromRabbit(queue, callback, options);
708
650
  }
709
651
 
710
- // TODO: [QUORUM-PHASE-3] Delete consumeOld we do not use it anymore
652
+ // TODO: DELETE
711
653
  async consumeOld(queue: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any> {
712
654
  await this.consumeFromRabbitOld(queue, callback, options);
713
655
  }
@@ -735,17 +677,18 @@ class RabbitMq implements IAfRabbitMq {
735
677
  private async consumeFromRabbit(queue: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any> {
736
678
  const optionsWithDefaults = { ...DEFAULT_OPTIONS, ...options };
737
679
  RabbitMq.validateName('queue', queue);
680
+ this.saveConsumer(queue, callback, options);
738
681
  const uniqueId = randomUUID();
739
682
  const {
740
683
  limit, deadMessageTtl, useConsumeWithLock, lockTimeout, auditContext, enableRabbitTrace,
741
684
  } = optionsWithDefaults;
742
685
  if (useConsumeWithLock) {
743
686
  if (!this.redisLock) {
744
- throw new RabbitError('Usage of consumeWithLock requires RedisInstance');
687
+ throw new Error('Usage of consumeWithLock requires RedisInstance');
745
688
  }
746
689
  logger.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
747
690
  }
748
- const channel = await this.getNewChannel({ connection: this.consumeConnection });
691
+ const channel = await this.getNewChannel({});
749
692
  return channel.addSetup(async (confirmChannel: ConfirmChannel) => {
750
693
  const q = await this.assertQueue(queue, optionsWithDefaults);
751
694
  await confirmChannel.prefetch(limit, false);
@@ -756,9 +699,9 @@ class RabbitMq implements IAfRabbitMq {
756
699
  return null;
757
700
  }
758
701
 
759
- const traceId = msg.properties.headers![TRACING_HEADER];
760
- const userId = msg.properties.headers![USER_TRACING_HEADER];
761
- const automationId = msg.properties.headers![AUTOMATION_ID_HEADER];
702
+ const traceId = msg.properties.headers[TRACING_HEADER];
703
+ const userId = msg.properties.headers[USER_TRACING_HEADER];
704
+ const automationId = msg.properties.headers[AUTOMATION_ID_HEADER];
762
705
  const parsedMessage = RabbitMq.parseMsg(msg);
763
706
  const releaseLock = await this.lockRedisIfNeeded(parsedMessage, optionsWithDefaults);
764
707
  const trace = newTrace(traceTypes.RABBIT);
@@ -830,7 +773,7 @@ class RabbitMq implements IAfRabbitMq {
830
773
  logger.error(`rabbit: failed to consume from queue ${queue}`);
831
774
  } else {
832
775
  logger.info(`rabbit: adding tag ${consumerTag} to the array.`);
833
- this.consumersTags.set(queue, { channel: confirmChannel, consumerTag });
776
+ this.consumersTags.push([confirmChannel, consumerTag]);
834
777
  }
835
778
  });
836
779
  }
@@ -841,15 +784,10 @@ class RabbitMq implements IAfRabbitMq {
841
784
  RabbitMq.validateName('exchange', exchange);
842
785
  RabbitMq.validateName('queue', queue);
843
786
  const { limit, deadMessageTtl } = optionsWithDefaults;
844
- // TODO: [QUORUM-PHASE-3] Delete the if statement after all the queues are created as quorum queues
845
- if (options?.isQuorumQueue !== false && DISABLE_QUORUM_QUEUES_CONSUME !== 'true') {
787
+ if (options?.isQuorumQueue !== false) {
788
+ await this.assertVHost();
846
789
  await this.saveConsumer(queue, callback, options);
847
- const backoffConfig = getAssertVhostExponentialBackoffConfig();
848
- await backOff(() => this.assertVHost(), backoffConfig);
849
- const channel: ChannelWrapper = await this.getNewChannel({
850
- name: `consume-exchange-${exchange}-queue-${queue}`,
851
- connection: this.consumeConnection,
852
- });
790
+ const channel: ChannelWrapper = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
853
791
 
854
792
  await channel.addSetup(async (c: ConfirmChannel) => {
855
793
  const assertExchange = await assertExchangeFanout(c, exchange);
@@ -866,12 +804,10 @@ class RabbitMq implements IAfRabbitMq {
866
804
  ]);
867
805
  });
868
806
  }
869
- // TODO: [QUORUM-PHASE-3] Delete the old implementation
807
+
808
+ // TODO: DELETE OLD
870
809
  await this.saveConsumerOld(queue, callback, options);
871
- const channelOld: ChannelWrapper = await this.getNewChannelOld({
872
- name: `consume-exchange-${exchange}-queue-${queue}-old`,
873
- connection: this.oldConsumeConnection,
874
- });
810
+ const channelOld: ChannelWrapper = await this.getNewChannelOld({ name: `consume-exchange-${exchange}-queue-${queue}-old` });
875
811
  await channelOld.addSetup(async (c: ConfirmChannel) => {
876
812
  const assertExchange = await assertExchangeFanout(c, exchange);
877
813
  await c.assertQueue(queue);
@@ -889,25 +825,25 @@ class RabbitMq implements IAfRabbitMq {
889
825
  }
890
826
 
891
827
  // Used by the microservices to publish messages to the exchange
892
- // TODO: [QUORUM-PHASE-3] isQuorumQueue flag is not needed anymore because all the queues are created as quorum queues
893
828
  async publish(exchange: string, content: any, customHeaders?: any, isQuorumQueue = true) : Promise<boolean> {
894
- if (isQuorumQueue && DISABLE_QUORUM_QUEUES_PUBLISH !== 'true') {
829
+ // TODO: DELETE THE IF
830
+ if (isQuorumQueue) {
895
831
  return wrapSetImmediate(async () => {
896
832
  await this.assertVHost();
897
833
  RabbitMq.validateName('exchange', exchange);
898
- const channel: ChannelWrapper = await this.assertChannel({ connection: this.publishConnection });
899
- await this.assertExchange(exchange, this.publishConnection);
834
+ const channel: ChannelWrapper = await this.assertChannel();
835
+ await this.assertExchange(exchange);
900
836
  await channel.publish(exchange, '',
901
837
  Buffer.from(JSON.stringify(content)),
902
838
  RabbitMq.getPublishOptions(customHeaders));
903
839
  });
904
840
  }
905
841
 
906
- // TODO: [QUORUM-PHASE-3] Delete the old implementation
842
+ // TODO: DELETE THE OLD
907
843
  return wrapSetImmediate(async () => {
908
844
  RabbitMq.validateName('exchange', exchange);
909
- const channel: ChannelWrapper = await this.assertChannelOld({ connection: this.oldPublishConnection });
910
- await this.assertExchangeOld(exchange, this.oldPublishConnection);
845
+ const channel: ChannelWrapper = await this.assertChannelOld();
846
+ await this.assertExchangeOld(exchange);
911
847
  await channel.publish(exchange, '',
912
848
  Buffer.from(JSON.stringify(content)),
913
849
  RabbitMq.getPublishOptions(customHeaders));
@@ -915,7 +851,6 @@ class RabbitMq implements IAfRabbitMq {
915
851
  }
916
852
 
917
853
  // Used by the microservices to send messages to the queue
918
- // TODO: [QUORUM-PHASE-3] isQuorumQueue flag is not needed anymore because all the queues are created as quorum queues
919
854
  async sendToQueue(
920
855
  queue: string,
921
856
  content: any,
@@ -923,10 +858,11 @@ class RabbitMq implements IAfRabbitMq {
923
858
  customHeaders?: any,
924
859
  isQuorumQueue = true,
925
860
  ): Promise<boolean | undefined> {
926
- if (isQuorumQueue && DISABLE_QUORUM_QUEUES_PUBLISH !== 'true') {
861
+ // TODO: DELETE THE IF AND THE OLD
862
+ if (isQuorumQueue) {
927
863
  try {
928
864
  await this.assertVHost();
929
- await this.assertChannel({ connection: this.publishConnection });
865
+ await this.assertChannel();
930
866
  } catch (e) {
931
867
  logger.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
932
868
  throw e;
@@ -941,7 +877,7 @@ class RabbitMq implements IAfRabbitMq {
941
877
  }
942
878
 
943
879
  try {
944
- const res = await this.publishChannel?.sendToQueue(queue,
880
+ const res = await this.channel?.sendToQueue(queue,
945
881
  Buffer.from(JSON.stringify(content)),
946
882
  RabbitMq.getPublishOptions(customHeaders));
947
883
  debug(`rabbit: sending to queue ${queue}`, { res });
@@ -953,97 +889,64 @@ class RabbitMq implements IAfRabbitMq {
953
889
  }
954
890
  } else {
955
891
  try {
956
- await this.assertChannelOld({ connection: this.oldPublishConnection });
892
+ await this.assertChannelOld();
957
893
  } catch (e) {
958
894
  logger.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
959
895
  throw e;
960
896
  }
897
+ }
961
898
 
962
- try {
963
- RabbitMq.validateName('queue', queue);
964
- await this.assertQueueOld(queue, options);
965
- } catch (e) {
966
- logger.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
967
- throw e;
968
- }
899
+ try {
900
+ RabbitMq.validateName('queue', queue);
901
+ await this.assertQueueOld(queue, options);
902
+ } catch (e) {
903
+ logger.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
904
+ throw e;
905
+ }
969
906
 
970
- try {
971
- const res = await this.oldPublishChannel?.sendToQueue(queue,
972
- Buffer.from(JSON.stringify(content)),
973
- RabbitMq.getPublishOptions(customHeaders));
974
- debug(`rabbit: sending to queue ${queue}`, { res });
975
- return res;
976
- } catch (e) {
977
- const isConnected = await this.isConnectedOld();
978
- logger.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
979
- throw e;
980
- }
907
+ try {
908
+ const res = await this.oldChannel?.sendToQueue(queue,
909
+ Buffer.from(JSON.stringify(content)),
910
+ RabbitMq.getPublishOptions(customHeaders));
911
+ debug(`rabbit: sending to queue ${queue}`, { res });
912
+ return res;
913
+ } catch (e) {
914
+ const isConnected = await this.isConnected();
915
+ logger.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
916
+ throw e;
981
917
  }
982
918
  }
983
919
 
984
- async isConnected(): Promise<boolean> {
985
- let isConnected = true;
986
- // TODO:[QUORUM-PHASE-3] Remove the condition
987
- if (!this.gracefulShutdownStarted) {
988
- if (DISABLE_QUORUM_QUEUES_CONSUME !== 'true' || DISABLE_QUORUM_QUEUES_PUBLISH !== 'true') {
989
- debug('rabbit: start is connected');
990
- const [consumeConnection, publishConnection] = await Promise.all([
991
- this.getConnection(this.consumeConnection),
992
- this.getConnection(this.publishConnection),
993
- ]);
994
- isConnected = consumeConnection.isConnected() && publishConnection.isConnected();
995
- if (!isConnected) {
996
- logger.error('rabbit: isConnected - false');
997
- return false;
998
- }
999
- try {
1000
- const unRegisteredConsumers = this.consumersToRegister.filter((c: AfConsumer) => {
1001
- const doesConsumerExist = this.consumersTags.get(c.queue);
1002
- return !doesConsumerExist;
1003
- });
1004
-
1005
- if (unRegisteredConsumers.length > 0) {
1006
- const queueNames = unRegisteredConsumers.map((c) => c.queue);
1007
-
1008
- logger.error('rabbit: found unregistered consumers for queues', {
1009
- count: queueNames.length,
1010
- queues: queueNames,
1011
- });
1012
- throw new RabbitError('Found unregistered consumers');
1013
- }
1014
- const channel: ChannelWrapper = await this.assertChannel({ connection: this.publishConnection });
1015
- await channel.waitForConnect();
1016
-
1017
- await Promise.all(
1018
- this.consumersToRegister.map((c: AfConsumer) => channel.checkQueue(c.queue)),
1019
- );
1020
- } catch (e: RabbitError | any) {
1021
- logger.error('rabbit: isConnected - false', { msg: e.message });
1022
- return false;
1023
- }
1024
- }
1025
- // TODO:[QUORUM-PHASE-3] Delete the old is connected and adjust the return value to return true
1026
- isConnected = await this.isConnectedOld();
920
+ async isConnected() : Promise<boolean> {
921
+ const connection = await this.getConnection();
922
+ const isConnected = connection.isConnected();
923
+ if (!isConnected) {
924
+ logger.error('rabbit: isConnected - false');
925
+ return false;
1027
926
  }
1028
-
1029
- logger.debug(`rabbit: isConnected - ${isConnected}`);
1030
- return isConnected;
927
+ const channel: any = await this.assertChannel();
928
+ try {
929
+ await Promise.all([
930
+ channel.waitForConnect(),
931
+ ...this.consumers.map((c: AfConsumer) => channel.checkQueue(c.queue)),
932
+ ]);
933
+ } catch (e) {
934
+ logger.error('rabbit: isConnected - false');
935
+ return false;
936
+ }
937
+ logger.info('rabbit: isConnected - true');
938
+ return true;
1031
939
  }
1032
940
 
1033
941
  async gracefulShutdown(signal: string) : Promise<void> {
1034
- // TODO: [QUORUM-PHASE-3] Delete the old implementation they are not needed anymore
1035
- this.gracefulShutdownStarted = true;
1036
- const tagsNumber = this.consumersTags.size + this.oldConsumersTags.size;
942
+ // TODO: DELETE OLD
943
+ const tagsNumber = this.consumersTags.length + this.oldConsumersTags.length;
1037
944
  logger.info(`rabbit: [gracefully-shutdown] received ${signal}! canceling #${tagsNumber} tags...`);
1038
- const cancelTagPromises = [...this.consumersTags].map(
1039
- ([_, { channel, consumerTag }]) => channel.cancel(consumerTag),
1040
- );
1041
- const cancelTagPromisesOld = [...this.oldConsumersTags].map(
1042
- ([_, { channel, consumerTag }]) => channel.cancel(consumerTag),
1043
- );
945
+ const cancelTagPromises = this.consumersTags.map(([channel, tag]) => channel.cancel(tag));
946
+ const cancelTagPromisesOld = this.oldConsumersTags.map(([channel, tag]) => channel.cancel(tag));
1044
947
  // Clean the array to avoid race
1045
- this.consumersTags.clear();
1046
- this.oldConsumersTags.clear();
948
+ this.consumersTags = [];
949
+ this.oldConsumersTags = [];
1047
950
  const results = await Promise.allSettled([...cancelTagPromises, ...cancelTagPromisesOld]);
1048
951
  const rejected = results.filter((p) => p.status === 'rejected');
1049
952
  if (rejected.length > 0) {
@@ -1056,17 +959,18 @@ class RabbitMq implements IAfRabbitMq {
1056
959
  private async consumeFromRabbitOld(queue: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any> {
1057
960
  const optionsWithDefaults = { ...DEFAULT_OPTIONS, ...options };
1058
961
  RabbitMq.validateName('queue', queue);
962
+ this.saveConsumerOld(queue, callback, options);
1059
963
  const uniqueId = randomUUID();
1060
964
  const {
1061
965
  limit, deadMessageTtl, useConsumeWithLock, lockTimeout, auditContext, enableRabbitTrace,
1062
966
  } = optionsWithDefaults;
1063
967
  if (useConsumeWithLock) {
1064
968
  if (!this.redisLock) {
1065
- throw new RabbitError('Usage of consumeWithLock requires RedisInstance');
969
+ throw new Error('Usage of consumeWithLock requires RedisInstance');
1066
970
  }
1067
971
  logger.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
1068
972
  }
1069
- const channel = await this.getNewChannelOld({ connection: this.oldConsumeConnection });
973
+ const channel = await this.getNewChannelOld({});
1070
974
  return channel.addSetup(async (confirmChannel: ConfirmChannel) => {
1071
975
  const q = await this.assertQueueOld(queue, optionsWithDefaults);
1072
976
  await confirmChannel.prefetch(limit, false);
@@ -1077,9 +981,9 @@ class RabbitMq implements IAfRabbitMq {
1077
981
  return null;
1078
982
  }
1079
983
 
1080
- const traceId = msg.properties.headers![TRACING_HEADER];
1081
- const userId = msg.properties.headers![USER_TRACING_HEADER];
1082
- const automationId = msg.properties.headers![AUTOMATION_ID_HEADER];
984
+ const traceId = msg.properties.headers[TRACING_HEADER];
985
+ const userId = msg.properties.headers[USER_TRACING_HEADER];
986
+ const automationId = msg.properties.headers[AUTOMATION_ID_HEADER];
1083
987
  const parsedMessage = RabbitMq.parseMsg(msg);
1084
988
  const releaseLock = await this.lockRedisIfNeeded(parsedMessage, optionsWithDefaults);
1085
989
  const trace = newTrace(traceTypes.RABBIT);
@@ -1148,34 +1052,24 @@ class RabbitMq implements IAfRabbitMq {
1148
1052
  }, CONSUMER_DEFAULT_OPTIONS,
1149
1053
  );
1150
1054
  if (!consumerTag) {
1151
- logger.error(`rabbit: failed to consume from queue ${queue} old`);
1055
+ logger.error(`rabbit: failed to consume from queue ${queue}`);
1152
1056
  } else {
1153
- logger.info(`rabbit: adding tag ${consumerTag} to the array old`);
1154
- this.oldConsumersTags.set(queue, { channel: confirmChannel, consumerTag });
1057
+ logger.info(`rabbit: adding tag ${consumerTag} to the array.`);
1058
+ this.oldConsumersTags.push([confirmChannel, consumerTag]);
1155
1059
  }
1156
1060
  });
1157
1061
  }
1158
1062
 
1159
- // TODO: [QUORUM-PHASE-3] Delete all the function under this line.
1160
- async getNewChannelOld({
1161
- name = rand().toString(),
1162
- onClose = null,
1163
- options = {},
1164
- connection,
1165
- }: newChannelOpts) {
1166
- let localConnection!: AmqpConnectionManager;
1063
+ // TODO: DELETE OLD PROPERTIES UNDER THIS LINE
1064
+ async getNewChannelOld({ name = rand().toString(), onClose = null, options = {} }: newChannelOpts = {}) {
1065
+ let connection!: AmqpConnectionManager;
1167
1066
  try {
1168
- localConnection = await this.getConnectionOld(connection);
1067
+ connection = await this.getConnectionOld();
1169
1068
  } catch (e) {
1170
1069
  logger.error(`rabbit: error on get connection for new channel ${name} `, { e });
1171
1070
  throw e;
1172
1071
  }
1173
-
1174
- if (!localConnection) {
1175
- throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
1176
- }
1177
-
1178
- const channel = localConnection?.createChannel({ ...options });
1072
+ const channel = connection.createChannel({ ...options });
1179
1073
  once(channel, 'close').then((args) => {
1180
1074
  logger.error(`rabbit: channel ${name} closed`);
1181
1075
  onClose?.(args);
@@ -1190,38 +1084,30 @@ class RabbitMq implements IAfRabbitMq {
1190
1084
  }
1191
1085
  }
1192
1086
 
1193
- async getConnectionOld(connection: ConnectionData) {
1087
+ async getConnectionOld() {
1194
1088
  return new Promise<AmqpConnectionManager>(async (resolve, reject) => {
1195
- const {
1196
- amqpConnection: connectionLocal,
1197
- creatingConnection,
1198
- connectionCreatedEventName,
1199
- connectionFailedEventName,
1200
- blockReconnect,
1201
- } = connection;
1202
-
1203
- if (blockReconnect) {
1089
+ if (this.oldBlockReconnect) {
1204
1090
  debug('rabbit: block reconnect');
1205
1091
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1206
1092
  // @ts-ignore
1207
1093
  return resolve();
1208
1094
  }
1209
- if (connectionLocal !== null) {
1210
- if (this.options?.disableReconnect || connectionLocal?.isConnected()) {
1095
+ if (this.oldConnection !== null) {
1096
+ if (this.options?.disableReconnect || this.oldConnection?.isConnected()) {
1211
1097
  debug('rabbit: connection - is connected');
1212
1098
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
1213
1099
  // @ts-ignore
1214
- return resolve(connectionLocal);
1100
+ return resolve(this.oldConnection);
1215
1101
  }
1216
1102
  debug('rabbit: connection - reconnecting');
1217
1103
  }
1218
- if (creatingConnection) {
1104
+ if (this.oldCreatingConnection) {
1219
1105
  debug('rabbit: creating connection emi');
1220
- this.oldEm.once(connectionCreatedEventName, resolve);
1221
- this.oldEm.once(connectionFailedEventName, reject);
1106
+ this.oldEm.once(CONNECTION_CREATED_CONST, resolve);
1107
+ this.oldEm.once(CONNECTION_FAILED_CONST, reject);
1222
1108
  return;
1223
1109
  }
1224
- connection.creatingConnection = true;
1110
+ this.oldCreatingConnection = true;
1225
1111
  let isResolved = false;
1226
1112
 
1227
1113
  // It is import to use it as a function and not as a variable
@@ -1238,59 +1124,56 @@ class RabbitMq implements IAfRabbitMq {
1238
1124
  };
1239
1125
 
1240
1126
  const defaultUrls = findServers();
1241
- const newConnection: AmqpConnectionManager = await connect(defaultUrls, {
1127
+ const connection: AmqpConnectionManager = await connect(defaultUrls, {
1242
1128
  findServers,
1243
1129
  });
1244
1130
 
1245
- connection.amqpConnection = newConnection;
1246
- newConnection.on('error', (err) => {
1131
+ this.oldConnection = connection;
1132
+ this.oldConnection.on('error', (err) => {
1247
1133
  logger.error('rabbit: connection error', { err });
1248
1134
  if (!isResolved) {
1249
1135
  isResolved = true;
1250
1136
  reject(err);
1251
- this.oldEm.emit(connectionFailedEventName, err);
1137
+ this.oldEm.emit(CONNECTION_FAILED_CONST, err);
1252
1138
  }
1253
1139
  });
1254
1140
 
1255
- newConnection.on('connectFailed', (err) => {
1256
- this.oldConsumersTags.clear();
1257
- if (typeof err.url === 'string') {
1258
- err.url = this.maskURL(err.url);
1259
- }
1141
+ this.oldConnection.on('connectFailed', (err) => {
1142
+ this.oldConsumersTags = [];
1260
1143
  logger.error('rabbit: connection connectFailed', { err });
1261
1144
  if (!isResolved) {
1262
1145
  isResolved = true;
1263
1146
  reject(err);
1264
- this.oldEm.emit(connectionFailedEventName, err);
1147
+ this.oldEm.emit(CONNECTION_FAILED_CONST, err);
1265
1148
  }
1266
1149
  });
1267
1150
 
1268
- newConnection.on('disconnect', ({ err }) => {
1269
- this.oldConsumersTags.clear();
1151
+ this.oldConnection.on('disconnect', ({ err }) => {
1152
+ this.oldConsumersTags = [];
1270
1153
  debug('rabbit: connection closed');
1271
1154
  if (this.options?.disableReconnect) {
1272
1155
  logger.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
1273
- connection.blockReconnect = true;
1156
+ this.oldBlockReconnect = true;
1274
1157
  } else {
1275
1158
  logger.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
1276
1159
  }
1277
1160
  });
1278
1161
 
1279
- newConnection.once('connect', async () => {
1162
+ this.oldConnection.once('connect', async () => {
1280
1163
  debug('rabbit: connection established');
1281
- connection.creatingConnection = false;
1282
- this.oldEm.emit(connectionCreatedEventName, newConnection);
1164
+ this.oldCreatingConnection = false;
1165
+ this.oldEm.emit(CONNECTION_CREATED_CONST, connection);
1283
1166
  isResolved = true;
1284
- resolve(newConnection);
1167
+ resolve(connection);
1285
1168
  });
1286
1169
  });
1287
1170
  }
1288
1171
 
1289
1172
  private saveConsumerOld(queue: string, callback: CallbackFunction, options: ConsumeOptions | undefined) {
1290
- const isConsumerExist: boolean = this.oldConsumersToRegister.some((consumer) => consumer.queue === queue);
1173
+ const isConsumerExist :boolean = this.oldConsumers.some((consumer) => consumer.queue === queue);
1291
1174
  if (!isConsumerExist) {
1292
1175
  logger.info(`rabbit: consumer: ${queue} saved in consumer array`);
1293
- this.oldConsumersToRegister.push({
1176
+ this.oldConsumers.push({
1294
1177
  queue,
1295
1178
  callback,
1296
1179
  options,
@@ -1315,7 +1198,6 @@ class RabbitMq implements IAfRabbitMq {
1315
1198
 
1316
1199
  async setupQueueOld(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue> {
1317
1200
  let queue: Replies.AssertQueue;
1318
- const connection = this.oldPublishConnection;
1319
1201
  const shouldUseQuorum = RabbitMq.shouldUseQuorum(queueName);
1320
1202
  const localeOptions = {
1321
1203
  ...options,
@@ -1327,7 +1209,7 @@ class RabbitMq implements IAfRabbitMq {
1327
1209
  },
1328
1210
  };
1329
1211
  try {
1330
- const channel: ChannelWrapper = await this.assertChannelOld({ connection });
1212
+ const channel: ChannelWrapper = await this.assertChannelOld();
1331
1213
  debug('assertQueue->channel.addSetup', { queueName });
1332
1214
  await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
1333
1215
  debug('assertQueue->channel.assertQueue', { queueName });
@@ -1336,8 +1218,8 @@ class RabbitMq implements IAfRabbitMq {
1336
1218
  logger.error('rabbit: assertQueue error', { queueName, options, error: e });
1337
1219
  if (!this.options?.dontRetryAssert) {
1338
1220
  debug('retrying assertQueue', { queueName });
1339
- const channel = await this.assertChannelOld({ force: true, connection });
1340
- await this.deleteQueueOld(queueName, connection);
1221
+ const channel = await this.assertChannelOld({ force: true });
1222
+ await this.deleteQueueOld(queueName);
1341
1223
 
1342
1224
  debug('retrying assertQueue->channel.addSetup', { queueName });
1343
1225
  await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
@@ -1352,21 +1234,19 @@ class RabbitMq implements IAfRabbitMq {
1352
1234
  return queue;
1353
1235
  }
1354
1236
 
1355
- async assertChannelOld({ force = false, connection }: assertChannelOpts): Promise<ChannelWrapper> {
1237
+ async assertChannelOld({ force = false } : assertChannelOpts = {}): Promise<ChannelWrapper> {
1356
1238
  if (!this.oldPublishChannelSetupPromise) {
1357
1239
  this.oldPublishChannelSetupPromise = new Promise<ChannelWrapper>(async (resolve, reject) => {
1358
- if (this.oldPublishChannel && !force) {
1359
- return resolve(this.oldPublishChannel);
1240
+ if (this.oldChannel && !force) {
1241
+ return resolve(this.oldChannel);
1360
1242
  }
1361
1243
 
1362
1244
  try {
1363
- const channel = await this.getNewChannelOld({ connection });
1245
+ const channel = await this.getNewChannelOld({});
1364
1246
  channel.on('error', (err) => {
1365
1247
  logger.error('rabbit: channel error', { err });
1366
1248
  });
1367
- if (this.oldPublishConnection === connection) {
1368
- this.oldPublishChannel = channel;
1369
- }
1249
+ this.oldChannel = channel;
1370
1250
  resolve(channel);
1371
1251
  } catch (e) {
1372
1252
  reject(e);
@@ -1376,17 +1256,17 @@ class RabbitMq implements IAfRabbitMq {
1376
1256
  return this.oldPublishChannelSetupPromise;
1377
1257
  }
1378
1258
 
1379
- private async deleteQueueOld(queue: string, connection: ConnectionData) {
1259
+ private async deleteQueueOld(queue: string) {
1380
1260
  RabbitMq.validateName('queue', queue);
1381
- const channel: ChannelWrapper = await this.assertChannelOld({ connection });
1261
+ const channel: ChannelWrapper = await this.assertChannelOld();
1382
1262
  logger.info('rabbit: deleting queue', { queue });
1383
1263
  const deleteQueueRes = await channel.deleteQueue(queue);
1384
1264
  debug('queue deleted', deleteQueueRes);
1385
1265
  return deleteQueueRes;
1386
1266
  }
1387
1267
 
1388
- async assertExchangeOld(exchangeName: string, connection: ConnectionData) {
1389
- const channel: ChannelWrapper = await this.assertChannelOld({ connection });
1268
+ async assertExchangeOld(exchangeName: string, options?: any) {
1269
+ const channel: ChannelWrapper = await this.assertChannelOld();
1390
1270
 
1391
1271
  if (this.oldExchanges[exchangeName]) {
1392
1272
  delete this.oldAssertExchangePromises[exchangeName];
@@ -1401,60 +1281,6 @@ class RabbitMq implements IAfRabbitMq {
1401
1281
  this.oldExchanges[exchangeName] = await this.oldAssertExchangePromises[exchangeName];
1402
1282
  return this.oldExchanges[exchangeName];
1403
1283
  }
1404
-
1405
- async isConnectedOld() : Promise<boolean> {
1406
- if (!this.gracefulShutdownStarted) {
1407
- debug('rabbit: start is connected old');
1408
- const [oldConsumeConnection, oldPublishConnection] = await Promise.all([
1409
- this.getConnectionOld(this.oldConsumeConnection),
1410
- this.getConnectionOld(this.oldPublishConnection),
1411
- ]);
1412
- const isConnected = oldConsumeConnection.isConnected() && oldPublishConnection.isConnected();
1413
- if (!isConnected) {
1414
- logger.error('rabbit: isConnected old - false');
1415
- return false;
1416
- }
1417
-
1418
- try {
1419
- const unRegisteredConsumersOld = this.consumersToRegister.filter((c: AfConsumer) => {
1420
- const doesConsumerExist = this.consumersTags.get(c.queue);
1421
- return !doesConsumerExist;
1422
- });
1423
-
1424
- if (unRegisteredConsumersOld.length > 0) {
1425
- const queueNames = unRegisteredConsumersOld.map((c) => c.queue);
1426
-
1427
- logger.error('rabbit: found unregistered consumers for queues old', {
1428
- count: queueNames.length,
1429
- queues: queueNames,
1430
- });
1431
- throw new RabbitError('Found unregistered consumers old');
1432
- }
1433
-
1434
- const channelOld: any = await this.assertChannelOld({ connection: this.oldPublishConnection });
1435
- await channelOld.waitForConnect();
1436
-
1437
- await Promise.all(
1438
- this.oldConsumersToRegister.map((c: AfConsumer) => channelOld.checkQueue(c.queue)),
1439
- );
1440
- } catch (e: RabbitError | any) {
1441
- logger.error('rabbit: isConnected - false old', { msg: e.message });
1442
- return false;
1443
- }
1444
- }
1445
- return true;
1446
- }
1447
-
1448
- private maskURL = (url: string): string => {
1449
- try {
1450
- const urlObj = new URL(url);
1451
- urlObj.username = '***';
1452
- urlObj.password = '***';
1453
- return urlObj.toString();
1454
- } catch {
1455
- return url;
1456
- }
1457
- }
1458
1284
  }
1459
1285
 
1460
1286
  export default RabbitMq;