@autofleet/rabbit 2.1.6 → 2.1.8-beta1

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.
package/.env ADDED
File without changes
package/dist/index.d.ts CHANGED
@@ -2,35 +2,15 @@
2
2
  import { Options } from 'amqplib';
3
3
  import { AmqpConnectionManager, ChannelWrapper } from 'amqp-connection-manager';
4
4
  import { EventEmitter } from 'events';
5
- import { RedisConfig } from './redis';
6
- export interface IAfRabbitMq {
7
- ack: any;
8
- nack: any;
9
- assertChannel: any;
10
- assertExchange: any;
11
- assertQueue: any;
12
- consume: any;
13
- consumeFromExchange: any;
14
- publish: any;
15
- sendToQueue: any;
16
- redisClient?: any;
17
- }
18
5
  interface ExchangesCache {
19
6
  [key: string]: any;
20
7
  }
21
- declare type CustomMessageHeaders = {
22
- redisTimestampValidationKey?: string;
23
- };
24
8
  export interface AfRabbitOptions {
25
9
  reconnect: boolean;
26
10
  }
27
- declare class RabbitMq implements IAfRabbitMq {
11
+ declare class RabbitMq {
28
12
  static parseMsg(msg: any): any;
29
13
  static validateName(type: string, name: string): void;
30
- static getPublishOptions(customHeaders?: CustomMessageHeaders): {
31
- timestamp: number;
32
- headers: CustomMessageHeaders;
33
- };
34
14
  PUBLISH_TIMEOUT: number;
35
15
  PUBLISH_ERROR_MSG: string;
36
16
  DISCONNECT_MSG: string;
@@ -41,11 +21,9 @@ declare class RabbitMq implements IAfRabbitMq {
41
21
  creatingConnection: boolean;
42
22
  exchanges: ExchangesCache;
43
23
  options: AfRabbitOptions | undefined;
44
- redisClient: any;
45
- constructor(options?: AfRabbitOptions, redisConfig?: RedisConfig);
46
- private shouldConsumeMessageByTimestamp;
47
- ack: (channel: ChannelWrapper, shouldUpdateRedisTimestamp?: boolean) => (msg: any) => Promise<void>;
48
- nack: (channel: ChannelWrapper, queue: string, options: any, deadQueueOptions: Options.AssertQueue) => (msg: any, { skipRetry, }?: any) => Promise<void>;
24
+ constructor(options?: AfRabbitOptions);
25
+ ack: (msg: any) => Promise<void>;
26
+ nack: (queue: string, options: any, deadQueueOptions: Options.AssertQueue) => (msg: any, { skipRetry, }?: any) => Promise<void>;
49
27
  getConnection(): Promise<AmqpConnectionManager>;
50
28
  getNewChannel(): Promise<ChannelWrapper>;
51
29
  assertChannel(): Promise<ChannelWrapper>;
@@ -55,8 +33,7 @@ declare class RabbitMq implements IAfRabbitMq {
55
33
  assertQueue(queue: string, options?: Options.AssertQueue): Promise<void>;
56
34
  consume(queue: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any): Promise<void>;
57
35
  consumeFromExchange(queue: string, exchange: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any): Promise<void>;
58
- publish(exchange: string, content: any, customHeaders?: any): Promise<unknown>;
59
- sendToQueue(queue: string, content: any, options?: any, customHeaders?: any): Promise<void>;
60
- isConnected(): Promise<boolean>;
36
+ publish(exchange: string, content: any): Promise<unknown>;
37
+ sendToQueue(queue: string, content: any, options?: any): Promise<void>;
61
38
  }
62
39
  export default RabbitMq;
package/dist/index.js CHANGED
@@ -34,45 +34,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
34
34
  /* eslint-disable @typescript-eslint/ban-ts-comment,@typescript-eslint/ban-types,@typescript-eslint/no-unused-vars,consistent-return,no-async-promise-executor,no-param-reassign,no-empty */
35
35
  // eslint-disable-next-line max-classes-per-file
36
36
  const bluebird = __importStar(require("bluebird"));
37
- const moment_1 = __importDefault(require("moment"));
38
37
  const amqp_connection_manager_1 = require("amqp-connection-manager");
39
38
  const events_1 = require("events");
40
39
  const outbreak_1 = require("@autofleet/outbreak");
41
40
  const rabbitError_1 = __importDefault(require("./rabbitError"));
42
- const redis_1 = __importDefault(require("./redis"));
43
41
  const DEFAULT_DEAD_TTL_TWO_DAYS = 60000 * 60 * 48;
44
42
  const defaultOptions = {
45
43
  limit: 1,
46
44
  retries: 1,
47
45
  deadMessageTtl: DEFAULT_DEAD_TTL_TWO_DAYS,
48
46
  };
49
- const SECONDS_TO_MILLISECONDS = 1000;
50
47
  const assertExchangeFanout = (c, exchangeName) => c.assertExchange(exchangeName, 'fanout');
51
48
  const connectionCreatedConst = 'connectionCreated';
52
49
  class RabbitMq {
53
- constructor(options, redisConfig) {
50
+ constructor(options) {
54
51
  this.PUBLISH_TIMEOUT = Number(process.env.RABBITMQ_PUBLISH_TIMEOUT) || 60000;
55
52
  this.PUBLISH_ERROR_MSG = `rabbit: publish timeout(${this.PUBLISH_TIMEOUT}ms) has pass, exchange: `;
56
53
  this.DISCONNECT_MSG = 'rabbit: connection disconnect';
57
54
  this.RESCONNECT_MSG = 'rabbit: reconnecting';
58
- this.shouldConsumeMessageByTimestamp = (msg) => __awaiter(this, void 0, void 0, function* () {
59
- const { properties: { timestamp, headers } } = msg;
60
- if (timestamp && (headers === null || headers === void 0 ? void 0 : headers.redisTimestampValidationKey) && this.redisClient) {
61
- const lastMessageTimestamp = yield this.redisClient.getAsync(headers.redisTimestampValidationKey);
62
- return !lastMessageTimestamp || moment_1.default(parseInt(lastMessageTimestamp, 10) * SECONDS_TO_MILLISECONDS).isBefore(moment_1.default(timestamp * SECONDS_TO_MILLISECONDS));
55
+ this.ack = (msg) => __awaiter(this, void 0, void 0, function* () {
56
+ if (this.channel) {
57
+ yield this.channel.ack(msg);
63
58
  }
64
- return true;
65
59
  });
66
- this.ack = (channel, shouldUpdateRedisTimestamp = false) => (msg) => __awaiter(this, void 0, void 0, function* () {
67
- yield channel.ack(msg);
68
- const { properties: { timestamp, headers } } = msg;
69
- if (shouldUpdateRedisTimestamp && timestamp && (headers === null || headers === void 0 ? void 0 : headers.redisTimestampValidationKey) && this.redisClient) {
70
- const parsedTimestamp = parseInt(timestamp, 10);
71
- yield this.redisClient.setAsync(headers.redisTimestampValidationKey, parsedTimestamp, 'EX', 3600);
72
- }
73
- });
74
- this.nack = (channel, queue, options, deadQueueOptions) => (msg, { skipRetry = false, } = {}) => __awaiter(this, void 0, void 0, function* () {
75
- if (channel) {
60
+ this.nack = (queue, options, deadQueueOptions) => (msg, { skipRetry = false, } = {}) => __awaiter(this, void 0, void 0, function* () {
61
+ if (this.channel) {
76
62
  if (!skipRetry
77
63
  && (!msg.content['x-retry-count']
78
64
  || msg.content['x-retry-count'] < options.retries)) {
@@ -84,7 +70,7 @@ class RabbitMq {
84
70
  yield this.assertQueue(deadQueue, deadQueueOptions);
85
71
  yield this.sendToQueue(deadQueue, msg.content, deadQueueOptions);
86
72
  }
87
- yield channel.ack(msg);
73
+ yield this.channel.ack(msg);
88
74
  }
89
75
  });
90
76
  this.em = new events_1.EventEmitter();
@@ -93,7 +79,6 @@ class RabbitMq {
93
79
  this.creatingConnection = false;
94
80
  this.exchanges = {};
95
81
  this.options = options;
96
- this.redisClient = redisConfig && redis_1.default(redisConfig);
97
82
  }
98
83
  static parseMsg(msg) {
99
84
  let { content } = msg;
@@ -109,12 +94,6 @@ class RabbitMq {
109
94
  throw new rabbitError_1.default(`error while using ${type} with no name`);
110
95
  }
111
96
  }
112
- static getPublishOptions(customHeaders = {}) {
113
- return {
114
- timestamp: moment_1.default().unix(),
115
- headers: customHeaders,
116
- };
117
- }
118
97
  getConnection() {
119
98
  return __awaiter(this, void 0, void 0, function* () {
120
99
  return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
@@ -123,13 +102,11 @@ class RabbitMq {
123
102
  return;
124
103
  }
125
104
  if (this.connection !== null) {
126
- return resolve(this.connection);
105
+ return this.connection;
127
106
  }
128
107
  this.creatingConnection = true;
129
- const username = process.env.RABBITMQ_USERNAME || 'guest';
130
- const password = process.env.RABBITMQ_PASSWORD || 'guest';
131
108
  const host = process.env.RABBITMQ_SERVICE_HOST || '';
132
- const connection = yield amqp_connection_manager_1.connect([`amqp://${username}:${password}@${host}`]);
109
+ const connection = yield amqp_connection_manager_1.connect([`amqp://${host}`]);
133
110
  this.connection = connection;
134
111
  this.connection.on('disconnect', ({ err }) => {
135
112
  var _a;
@@ -217,15 +194,10 @@ class RabbitMq {
217
194
  yield c.assertQueue(queue);
218
195
  yield c.prefetch(limit, true);
219
196
  return Promise.all([
220
- c.consume(queue, (msg) => __awaiter(this, void 0, void 0, function* () {
221
- const parsedMessage = RabbitMq.parseMsg(msg);
197
+ c.consume(queue, (msg) => {
222
198
  outbreak_1.newTrace(outbreak_1.traceTypes.RABBIT);
223
- const shouldConsume = yield this.shouldConsumeMessageByTimestamp(parsedMessage);
224
- if (!shouldConsume) {
225
- return this.ack(channel)(msg);
226
- }
227
- callback(parsedMessage, this.ack(channel, true), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
228
- })),
199
+ callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
200
+ }),
229
201
  ]);
230
202
  }));
231
203
  });
@@ -244,47 +216,31 @@ class RabbitMq {
244
216
  yield c.prefetch(limit, true);
245
217
  return Promise.all([
246
218
  c.bindQueue(queue, exchange, ''),
247
- c.consume(queue, (msg) => __awaiter(this, void 0, void 0, function* () {
248
- const parsedMessage = RabbitMq.parseMsg(msg);
219
+ c.consume(queue, (msg) => {
249
220
  outbreak_1.newTrace(outbreak_1.traceTypes.RABBIT);
250
- const shouldConsume = yield this.shouldConsumeMessageByTimestamp(parsedMessage);
251
- if (!shouldConsume) {
252
- return this.ack(channel)(msg);
253
- }
254
- callback(parsedMessage, this.ack(channel, true), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
255
- })),
221
+ callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
222
+ }),
256
223
  ]);
257
224
  }));
258
225
  });
259
226
  }
260
- publish(exchange, content, customHeaders) {
227
+ publish(exchange, content) {
261
228
  return __awaiter(this, void 0, void 0, function* () {
262
229
  RabbitMq.validateName('exchange', exchange);
263
230
  const channel = yield this.assertChannel();
264
231
  yield this.assertExchange(exchange);
265
- return new bluebird.Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
266
- try {
267
- yield channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
268
- return resolve();
269
- }
270
- catch (e) {
271
- reject(e);
272
- }
232
+ return new bluebird.Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
233
+ yield channel.publish(exchange, '', Buffer.from(JSON.stringify(content)));
234
+ return resolve();
273
235
  })).timeout(this.PUBLISH_TIMEOUT, `${this.PUBLISH_ERROR_MSG}${exchange}`);
274
236
  });
275
237
  }
276
- sendToQueue(queue, content, options, customHeaders) {
238
+ sendToQueue(queue, content, options) {
277
239
  return __awaiter(this, void 0, void 0, function* () {
278
240
  RabbitMq.validateName('queue', queue);
279
241
  const channel = yield this.assertChannel();
280
242
  yield this.assertQueue(queue, options);
281
- return channel.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
282
- });
283
- }
284
- isConnected() {
285
- return __awaiter(this, void 0, void 0, function* () {
286
- const connection = yield this.getConnection();
287
- return connection.isConnected();
243
+ return channel.sendToQueue(queue, Buffer.from(JSON.stringify(content)));
288
244
  });
289
245
  }
290
246
  }
package/dist/mock.d.ts CHANGED
@@ -1,14 +1,13 @@
1
1
  import 'jest';
2
- import { IAfRabbitMq } from './index';
3
- declare class RabbitMq implements IAfRabbitMq {
4
- ack: any;
5
- nack: any;
6
- assertChannel: any;
7
- assertExchange: any;
8
- assertQueue: any;
9
- consume: any;
10
- consumeFromExchange: any;
11
- publish: any;
12
- sendToQueue: any;
2
+ declare class RabbitMq {
3
+ ack: jest.Mock<unknown>;
4
+ nack: jest.Mock<unknown>;
5
+ assertChannel: jest.Mock<unknown>;
6
+ assertExchange: jest.Mock<unknown>;
7
+ assertQueue: jest.Mock<unknown>;
8
+ consume: jest.Mock<unknown>;
9
+ consumeFromExchange: jest.Mock<unknown>;
10
+ publish: jest.Mock<unknown>;
11
+ sendToQueue: jest.Mock<unknown>;
13
12
  }
14
13
  export default RabbitMq;
package/dist/mock.js CHANGED
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- // eslint-disable-next-line import/no-extraneous-dependencies
4
3
  require("jest");
5
4
  class RabbitMq {
6
5
  constructor() {
package/dump.rdb ADDED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/rabbit",
3
- "version": "2.1.6",
3
+ "version": "2.1.8-beta1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -15,6 +15,7 @@
15
15
  "dev": "nodemon"
16
16
  },
17
17
  "dependencies": {
18
+ "@autofleet/logger": "^1.2.8",
18
19
  "@types/amqp-connection-manager": "^2.0.10",
19
20
  "@types/amqplib": "^0.5.16",
20
21
  "@types/uuid": "^8.3.3",
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ import { ConfirmChannel, Options } from 'amqplib';
6
6
  import { AmqpConnectionManager, ChannelWrapper, connect } from 'amqp-connection-manager';
7
7
  import { EventEmitter } from 'events';
8
8
  import { newTrace, traceTypes } from '@autofleet/outbreak';
9
+ import logger from './logger';
9
10
  import RabbitError from './rabbitError';
10
11
  import getRedisInstance, { RedisConfig } from './redis';
11
12
 
@@ -110,7 +111,10 @@ class RabbitMq implements IAfRabbitMq {
110
111
  const { properties: { timestamp, headers } } = msg;
111
112
  if (timestamp && headers?.redisTimestampValidationKey && this.redisClient) {
112
113
  const lastMessageTimestamp = await this.redisClient.getAsync(headers.redisTimestampValidationKey);
113
- return !lastMessageTimestamp || moment(parseInt(lastMessageTimestamp, 10) * SECONDS_TO_MILLISECONDS).isBefore(moment(timestamp * SECONDS_TO_MILLISECONDS));
114
+ logger.info('rabbit: checking if should consume params', {
115
+ msg, timestamp, headers, lastMessageTimestamp,
116
+ });
117
+ return !lastMessageTimestamp || (parseInt(lastMessageTimestamp, 10) <= parseInt(timestamp, 10));
114
118
  }
115
119
  return true;
116
120
  }
@@ -155,7 +159,7 @@ class RabbitMq implements IAfRabbitMq {
155
159
  async getConnection() {
156
160
  return new Promise<AmqpConnectionManager>(async (resolve) => {
157
161
  if (this.creatingConnection) {
158
- this.em.on(connectionCreatedConst, resolve);
162
+ this.em.once(connectionCreatedConst, resolve);
159
163
  return;
160
164
  }
161
165
  if (this.connection !== null) {
@@ -193,9 +197,8 @@ class RabbitMq implements IAfRabbitMq {
193
197
  return resolve(this.channel);
194
198
  }
195
199
 
196
- const connection: AmqpConnectionManager = await this.getConnection();
197
-
198
200
  try {
201
+ const connection: AmqpConnectionManager = await this.getConnection();
199
202
  if (this.channel === null) {
200
203
  this.channel = connection.createChannel({});
201
204
  }
@@ -252,6 +255,7 @@ class RabbitMq implements IAfRabbitMq {
252
255
  const parsedMessage = RabbitMq.parseMsg(msg);
253
256
  newTrace(traceTypes.RABBIT);
254
257
  const shouldConsume = await this.shouldConsumeMessageByTimestamp(parsedMessage);
258
+ logger.info('rabbit: trying to consume', { queue, shouldConsume, msg });
255
259
  if (!shouldConsume) {
256
260
  return this.ack(channel)(msg);
257
261
  }
@@ -282,6 +286,7 @@ class RabbitMq implements IAfRabbitMq {
282
286
  const parsedMessage = RabbitMq.parseMsg(msg);
283
287
  newTrace(traceTypes.RABBIT);
284
288
  const shouldConsume = await this.shouldConsumeMessageByTimestamp(parsedMessage);
289
+ logger.info('rabbit: trying to consume', { queue, shouldConsume, msg });
285
290
  if (!shouldConsume) {
286
291
  return this.ack(channel)(msg);
287
292
  }
@@ -312,6 +317,7 @@ class RabbitMq implements IAfRabbitMq {
312
317
  RabbitMq.validateName('queue', queue);
313
318
  const channel: ChannelWrapper = await this.assertChannel();
314
319
  await this.assertQueue(queue, options);
320
+ logger.info('rabbit: sending to queue', { queue, content, customHeaders });
315
321
  return channel.sendToQueue(queue,
316
322
  Buffer.from(JSON.stringify(content)),
317
323
  RabbitMq.getPublishOptions(customHeaders));
package/src/logger.ts ADDED
@@ -0,0 +1,5 @@
1
+ const Logger = require('@autofleet/logger');
2
+
3
+ const logger = Logger();
4
+
5
+ export default logger;
package/dist/redis.d.ts DELETED
@@ -1,7 +0,0 @@
1
- export declare type RedisConfig = {
2
- host: string;
3
- port: number | undefined;
4
- prefix?: string;
5
- };
6
- declare const getRedisInstance: (config: RedisConfig) => any;
7
- export default getRedisInstance;
package/dist/redis.js DELETED
@@ -1,11 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const bluebird_1 = __importDefault(require("bluebird"));
7
- const redis = require('redis');
8
- bluebird_1.default.promisifyAll(redis.RedisClient.prototype);
9
- bluebird_1.default.promisifyAll(redis.Multi.prototype);
10
- const getRedisInstance = (config) => redis.createClient(config);
11
- exports.default = getRedisInstance;