@autofleet/rabbit 3.1.0 → 3.1.2
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/dist/index.js +35 -33
- package/dist/lib/consts.d.ts +1 -0
- package/dist/lib/consts.js +2 -1
- package/package.json +1 -1
- package/src/index.ts +38 -35
- package/src/lib/consts.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -128,15 +128,6 @@ class RabbitMq {
|
|
|
128
128
|
const user = trace?.context?.get(consts_1.USER_OBJECT);
|
|
129
129
|
const traceId = trace?.context?.get(consts_1.TRACING_HEADER);
|
|
130
130
|
const outbreakTrace = zehut_1.outbreak.getCurrentContext();
|
|
131
|
-
const obj = Object.fromEntries(trace?.context);
|
|
132
|
-
const jsonString = JSON.stringify(obj);
|
|
133
|
-
logger_1.default.info('getPublishOptions', {
|
|
134
|
-
traceId,
|
|
135
|
-
user,
|
|
136
|
-
traceId2: outbreakTrace?.context?.get(consts_1.TRACING_HEADER),
|
|
137
|
-
traceContextSize: trace?.context?.size,
|
|
138
|
-
jsonString,
|
|
139
|
-
});
|
|
140
131
|
return {
|
|
141
132
|
timestamp: moment_1.default().unix(),
|
|
142
133
|
headers: {
|
|
@@ -148,7 +139,7 @@ class RabbitMq {
|
|
|
148
139
|
};
|
|
149
140
|
}
|
|
150
141
|
async getConnection() {
|
|
151
|
-
return new Promise(async (resolve) => {
|
|
142
|
+
return new Promise(async (resolve, reject) => {
|
|
152
143
|
if (this.blockReconnect) {
|
|
153
144
|
debug('rabbit: block reconnect');
|
|
154
145
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -167,12 +158,30 @@ class RabbitMq {
|
|
|
167
158
|
if (this.creatingConnection) {
|
|
168
159
|
debug('rabbit: creating connection emi');
|
|
169
160
|
this.em.once(consts_1.CONNECTION_CREATED_CONST, resolve);
|
|
161
|
+
this.em.once(consts_1.CONNECTION_FAILED_CONST, reject);
|
|
170
162
|
return;
|
|
171
163
|
}
|
|
172
164
|
this.creatingConnection = true;
|
|
165
|
+
let isResolved = false;
|
|
173
166
|
debug('rabbit: creating connection', { HOST, USERNAME, HEARTBEAT });
|
|
174
167
|
const connection = await amqp_connection_manager_1.connect([`amqp://${USERNAME}:${PASSWORD}@${HOST}?heartbeat=${HEARTBEAT}}`]);
|
|
175
168
|
this.connection = connection;
|
|
169
|
+
this.connection.on('error', (err) => {
|
|
170
|
+
logger_1.default.error('rabbit: connection error', { err });
|
|
171
|
+
if (!isResolved) {
|
|
172
|
+
isResolved = true;
|
|
173
|
+
reject(err);
|
|
174
|
+
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
this.connection.on('connectFailed', (err) => {
|
|
178
|
+
logger_1.default.error('rabbit: connection connectFailed', { err });
|
|
179
|
+
if (!isResolved) {
|
|
180
|
+
isResolved = true;
|
|
181
|
+
reject(err);
|
|
182
|
+
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
176
185
|
this.connection.on('disconnect', ({ err }) => {
|
|
177
186
|
debug('rabbit: connection closed');
|
|
178
187
|
this.exchanges = {};
|
|
@@ -192,6 +201,7 @@ class RabbitMq {
|
|
|
192
201
|
await this.loadConsumers();
|
|
193
202
|
this.creatingConnection = false;
|
|
194
203
|
this.em.emit(consts_1.CONNECTION_CREATED_CONST, connection);
|
|
204
|
+
isResolved = true;
|
|
195
205
|
resolve(connection);
|
|
196
206
|
});
|
|
197
207
|
});
|
|
@@ -200,8 +210,13 @@ class RabbitMq {
|
|
|
200
210
|
return new Promise(async (resolve, reject) => {
|
|
201
211
|
const connection = await this.getConnection();
|
|
202
212
|
const channel = connection.createChannel({});
|
|
213
|
+
let isResolved = false;
|
|
203
214
|
channel.on('error', (err) => {
|
|
204
215
|
logger_1.default.error(`rabbit: channel ${name} error`, { err });
|
|
216
|
+
if (!isResolved) {
|
|
217
|
+
isResolved = true;
|
|
218
|
+
reject(err);
|
|
219
|
+
}
|
|
205
220
|
});
|
|
206
221
|
channel.on('close', (...args) => {
|
|
207
222
|
logger_1.default.error(`rabbit: channel ${name} closed`, { args });
|
|
@@ -211,6 +226,7 @@ class RabbitMq {
|
|
|
211
226
|
});
|
|
212
227
|
channel.once('connect', () => {
|
|
213
228
|
debug(`rabbit: channel ${name} CONNECTED`);
|
|
229
|
+
isResolved = true;
|
|
214
230
|
resolve(channel);
|
|
215
231
|
});
|
|
216
232
|
});
|
|
@@ -250,14 +266,12 @@ class RabbitMq {
|
|
|
250
266
|
return channel.checkQueue(queue);
|
|
251
267
|
}
|
|
252
268
|
async deleteQueue(queue) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
resolve(deleteQueueRes);
|
|
260
|
-
});
|
|
269
|
+
RabbitMq.validateName('queue', queue);
|
|
270
|
+
const channel = await this.assertChannel();
|
|
271
|
+
logger_1.default.info('rabbit: deleting queue', { queue });
|
|
272
|
+
const deleteQueueRes = await channel.deleteQueue(queue);
|
|
273
|
+
debug('queue deleted', deleteQueueRes);
|
|
274
|
+
return deleteQueueRes;
|
|
261
275
|
}
|
|
262
276
|
async bindQueue(queue, exchange) {
|
|
263
277
|
const channel = await this.assertChannel();
|
|
@@ -349,11 +363,13 @@ class RabbitMq {
|
|
|
349
363
|
}
|
|
350
364
|
const traceId = msg.properties.headers[consts_1.TRACING_HEADER];
|
|
351
365
|
const userId = msg.properties.headers[consts_1.USER_TRACING_HEADER];
|
|
352
|
-
logger_1.default.info('rabbit: consume', { traceId, userId, enableRabbitTrace });
|
|
353
366
|
const parsedMessage = RabbitMq.parseMsg(msg);
|
|
354
367
|
const releaseLock = await this.lockRedisIfNeeded(parsedMessage, optionsWithDefaults);
|
|
355
368
|
const trace = zehut_1.newTrace(zehut_1.traceTypes.RABBIT);
|
|
369
|
+
// setting also outbreak trace as part of legacy code
|
|
356
370
|
const outbreakTrace = zehut_1.outbreak.newTrace(zehut_1.traceTypes.RABBIT);
|
|
371
|
+
// enableRabbitTrace is a flag to protect from different flows that doesn't work with permission
|
|
372
|
+
// and we don't want to fail the flow because of it
|
|
357
373
|
if (userId && enableRabbitTrace) {
|
|
358
374
|
try {
|
|
359
375
|
await Promise.all([
|
|
@@ -366,24 +382,10 @@ class RabbitMq {
|
|
|
366
382
|
await this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg, releaseLock)(msg);
|
|
367
383
|
}
|
|
368
384
|
}
|
|
369
|
-
logger_1.default.info('rabbit consume - first trace', {
|
|
370
|
-
trace,
|
|
371
|
-
outbreakTrace,
|
|
372
|
-
user: trace?.context?.get(consts_1.USER_OBJECT),
|
|
373
|
-
});
|
|
374
385
|
if (traceId) {
|
|
375
386
|
trace?.context?.set(consts_1.TRACING_HEADER, traceId);
|
|
376
387
|
outbreakTrace?.context.set(consts_1.TRACING_HEADER, traceId);
|
|
377
|
-
logger_1.default.info('rabbit consume - second trace', {
|
|
378
|
-
trace,
|
|
379
|
-
outbreakTrace,
|
|
380
|
-
user: trace?.context?.get(consts_1.USER_OBJECT),
|
|
381
|
-
traceId: trace?.context?.get(consts_1.TRACING_HEADER),
|
|
382
|
-
});
|
|
383
388
|
}
|
|
384
|
-
logger_1.default.info('rabbit consume - third trace', {
|
|
385
|
-
trace: zehut_1.getCurrentPayload(),
|
|
386
|
-
});
|
|
387
389
|
if (auditContext) {
|
|
388
390
|
await auditContext(queue);
|
|
389
391
|
}
|
package/dist/lib/consts.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare const USER_TRACING_HEADER = "x-af-user-id";
|
|
|
6
6
|
export declare const USER_OBJECT = "userObject";
|
|
7
7
|
export declare const DEFAULT_USE_CONSUME_WITH_LOCK = false;
|
|
8
8
|
export declare const CONNECTION_CREATED_CONST = "connectionCreated";
|
|
9
|
+
export declare const CONNECTION_FAILED_CONST = "connectionFailed";
|
|
9
10
|
export declare const DEFAULT_OPTIONS: {
|
|
10
11
|
limit: number;
|
|
11
12
|
retries: number;
|
package/dist/lib/consts.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_OPTIONS = exports.CONNECTION_CREATED_CONST = exports.DEFAULT_USE_CONSUME_WITH_LOCK = exports.USER_OBJECT = exports.USER_TRACING_HEADER = exports.TRACING_HEADER = exports.RETRY_HEADER = exports.DEFAULT_LOCK_TIMEOUT = exports.DEFAULT_DEAD_TTL_TWO_DAYS = void 0;
|
|
3
|
+
exports.DEFAULT_OPTIONS = exports.CONNECTION_FAILED_CONST = exports.CONNECTION_CREATED_CONST = exports.DEFAULT_USE_CONSUME_WITH_LOCK = exports.USER_OBJECT = exports.USER_TRACING_HEADER = exports.TRACING_HEADER = exports.RETRY_HEADER = exports.DEFAULT_LOCK_TIMEOUT = exports.DEFAULT_DEAD_TTL_TWO_DAYS = void 0;
|
|
4
4
|
exports.DEFAULT_DEAD_TTL_TWO_DAYS = 60000 * 60 * 12;
|
|
5
5
|
exports.DEFAULT_LOCK_TIMEOUT = 1000 * 5;
|
|
6
6
|
exports.RETRY_HEADER = 'x-retry-count';
|
|
@@ -9,6 +9,7 @@ exports.USER_TRACING_HEADER = 'x-af-user-id';
|
|
|
9
9
|
exports.USER_OBJECT = 'userObject';
|
|
10
10
|
exports.DEFAULT_USE_CONSUME_WITH_LOCK = false;
|
|
11
11
|
exports.CONNECTION_CREATED_CONST = 'connectionCreated';
|
|
12
|
+
exports.CONNECTION_FAILED_CONST = 'connectionFailed';
|
|
12
13
|
exports.DEFAULT_OPTIONS = {
|
|
13
14
|
limit: 1,
|
|
14
15
|
retries: 1,
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -17,6 +17,7 @@ import getRedisInstance, { RedisConfig } from './lib/redis';
|
|
|
17
17
|
import { assertExchangeFanout, rand, wrapSetImmediate } from './lib/utils';
|
|
18
18
|
import {
|
|
19
19
|
CONNECTION_CREATED_CONST,
|
|
20
|
+
CONNECTION_FAILED_CONST,
|
|
20
21
|
DEFAULT_LOCK_TIMEOUT,
|
|
21
22
|
DEFAULT_OPTIONS,
|
|
22
23
|
RETRY_HEADER,
|
|
@@ -116,15 +117,6 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
116
117
|
const user = trace?.context?.get(USER_OBJECT);
|
|
117
118
|
const traceId = trace?.context?.get(TRACING_HEADER);
|
|
118
119
|
const outbreakTrace = outbreak.getCurrentContext();
|
|
119
|
-
const obj = Object.fromEntries(trace?.context);
|
|
120
|
-
const jsonString = JSON.stringify(obj);
|
|
121
|
-
logger.info('getPublishOptions', {
|
|
122
|
-
traceId,
|
|
123
|
-
user,
|
|
124
|
-
traceId2: outbreakTrace?.context?.get(TRACING_HEADER),
|
|
125
|
-
traceContextSize: trace?.context?.size,
|
|
126
|
-
jsonString,
|
|
127
|
-
});
|
|
128
120
|
return {
|
|
129
121
|
timestamp: moment().unix(),
|
|
130
122
|
headers: {
|
|
@@ -268,7 +260,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
268
260
|
}
|
|
269
261
|
|
|
270
262
|
async getConnection() {
|
|
271
|
-
return new Promise<AmqpConnectionManager>(async (resolve) => {
|
|
263
|
+
return new Promise<AmqpConnectionManager>(async (resolve, reject) => {
|
|
272
264
|
if (this.blockReconnect) {
|
|
273
265
|
debug('rabbit: block reconnect');
|
|
274
266
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -287,12 +279,32 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
287
279
|
if (this.creatingConnection) {
|
|
288
280
|
debug('rabbit: creating connection emi');
|
|
289
281
|
this.em.once(CONNECTION_CREATED_CONST, resolve);
|
|
282
|
+
this.em.once(CONNECTION_FAILED_CONST, reject);
|
|
290
283
|
return;
|
|
291
284
|
}
|
|
292
285
|
this.creatingConnection = true;
|
|
286
|
+
let isResolved = false;
|
|
293
287
|
debug('rabbit: creating connection', { HOST, USERNAME, HEARTBEAT });
|
|
294
288
|
const connection: AmqpConnectionManager = await connect([`amqp://${USERNAME}:${PASSWORD}@${HOST}?heartbeat=${HEARTBEAT}}`]);
|
|
295
289
|
this.connection = connection;
|
|
290
|
+
this.connection.on('error', (err) => {
|
|
291
|
+
logger.error('rabbit: connection error', { err });
|
|
292
|
+
if (!isResolved) {
|
|
293
|
+
isResolved = true;
|
|
294
|
+
reject(err);
|
|
295
|
+
this.em.emit(CONNECTION_FAILED_CONST, err);
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
this.connection.on('connectFailed', (err) => {
|
|
300
|
+
logger.error('rabbit: connection connectFailed', { err });
|
|
301
|
+
if (!isResolved) {
|
|
302
|
+
isResolved = true;
|
|
303
|
+
reject(err);
|
|
304
|
+
this.em.emit(CONNECTION_FAILED_CONST, err);
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
|
|
296
308
|
this.connection.on('disconnect', ({ err }) => {
|
|
297
309
|
debug('rabbit: connection closed');
|
|
298
310
|
this.exchanges = {};
|
|
@@ -311,6 +323,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
311
323
|
await this.loadConsumers();
|
|
312
324
|
this.creatingConnection = false;
|
|
313
325
|
this.em.emit(CONNECTION_CREATED_CONST, connection);
|
|
326
|
+
isResolved = true;
|
|
314
327
|
resolve(connection);
|
|
315
328
|
});
|
|
316
329
|
});
|
|
@@ -321,8 +334,13 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
321
334
|
const connection: AmqpConnectionManager = await this.getConnection();
|
|
322
335
|
const channel = connection.createChannel({});
|
|
323
336
|
|
|
337
|
+
let isResolved = false;
|
|
324
338
|
channel.on('error', (err) => {
|
|
325
339
|
logger.error(`rabbit: channel ${name} error`, { err });
|
|
340
|
+
if (!isResolved) {
|
|
341
|
+
isResolved = true;
|
|
342
|
+
reject(err);
|
|
343
|
+
}
|
|
326
344
|
});
|
|
327
345
|
channel.on('close', (...args) => {
|
|
328
346
|
logger.error(`rabbit: channel ${name} closed`, { args });
|
|
@@ -332,6 +350,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
332
350
|
});
|
|
333
351
|
channel.once('connect', () => {
|
|
334
352
|
debug(`rabbit: channel ${name} CONNECTED`);
|
|
353
|
+
isResolved = true;
|
|
335
354
|
resolve(channel);
|
|
336
355
|
});
|
|
337
356
|
});
|
|
@@ -375,14 +394,12 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
375
394
|
}
|
|
376
395
|
|
|
377
396
|
private async deleteQueue(queue: string) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
resolve(deleteQueueRes);
|
|
385
|
-
});
|
|
397
|
+
RabbitMq.validateName('queue', queue);
|
|
398
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
399
|
+
logger.info('rabbit: deleting queue', { queue });
|
|
400
|
+
const deleteQueueRes = await channel.deleteQueue(queue);
|
|
401
|
+
debug('queue deleted', deleteQueueRes);
|
|
402
|
+
return deleteQueueRes;
|
|
386
403
|
}
|
|
387
404
|
|
|
388
405
|
async bindQueue(queue: string, exchange: string) {
|
|
@@ -493,11 +510,13 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
493
510
|
|
|
494
511
|
const traceId = msg.properties.headers[TRACING_HEADER];
|
|
495
512
|
const userId = msg.properties.headers[USER_TRACING_HEADER];
|
|
496
|
-
logger.info('rabbit: consume', { traceId, userId, enableRabbitTrace });
|
|
497
513
|
const parsedMessage = RabbitMq.parseMsg(msg);
|
|
498
514
|
const releaseLock = await this.lockRedisIfNeeded(parsedMessage, optionsWithDefaults);
|
|
499
515
|
const trace = newTrace(traceTypes.RABBIT);
|
|
516
|
+
// setting also outbreak trace as part of legacy code
|
|
500
517
|
const outbreakTrace = outbreak.newTrace(traceTypes.RABBIT);
|
|
518
|
+
// enableRabbitTrace is a flag to protect from different flows that doesn't work with permission
|
|
519
|
+
// and we don't want to fail the flow because of it
|
|
501
520
|
if (userId && enableRabbitTrace) {
|
|
502
521
|
try {
|
|
503
522
|
await Promise.all([
|
|
@@ -510,27 +529,11 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
510
529
|
}
|
|
511
530
|
}
|
|
512
531
|
|
|
513
|
-
logger.info('rabbit consume - first trace', {
|
|
514
|
-
trace,
|
|
515
|
-
outbreakTrace,
|
|
516
|
-
user: trace?.context?.get(USER_OBJECT),
|
|
517
|
-
});
|
|
518
|
-
|
|
519
532
|
if (traceId) {
|
|
520
533
|
(trace as any)?.context?.set(TRACING_HEADER, traceId);
|
|
521
534
|
(outbreakTrace as any)?.context.set(TRACING_HEADER, traceId);
|
|
522
|
-
logger.info('rabbit consume - second trace', {
|
|
523
|
-
trace,
|
|
524
|
-
outbreakTrace,
|
|
525
|
-
user: trace?.context?.get(USER_OBJECT),
|
|
526
|
-
traceId: trace?.context?.get(TRACING_HEADER),
|
|
527
|
-
// traceId2: outbreakTrace?.context?.get(TRACING_HEADER),
|
|
528
|
-
});
|
|
529
535
|
}
|
|
530
536
|
|
|
531
|
-
logger.info('rabbit consume - third trace', {
|
|
532
|
-
trace: getCurrentPayload(),
|
|
533
|
-
});
|
|
534
537
|
if (auditContext) {
|
|
535
538
|
await auditContext(queue);
|
|
536
539
|
}
|
package/src/lib/consts.ts
CHANGED
|
@@ -6,6 +6,7 @@ export const USER_TRACING_HEADER = 'x-af-user-id';
|
|
|
6
6
|
export const USER_OBJECT = 'userObject';
|
|
7
7
|
export const DEFAULT_USE_CONSUME_WITH_LOCK = false;
|
|
8
8
|
export const CONNECTION_CREATED_CONST = 'connectionCreated';
|
|
9
|
+
export const CONNECTION_FAILED_CONST = 'connectionFailed';
|
|
9
10
|
export const DEFAULT_OPTIONS = {
|
|
10
11
|
limit: 1,
|
|
11
12
|
retries: 1,
|