@autofleet/rabbit 1.5.1 → 1.5.3
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/example.js +3 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +24 -12
- package/dist/index.test.js +22 -2
- package/dist/interfaces/RabbitWrapperInterface.d.ts +15 -0
- package/dist/interfaces/RabbitWrapperInterface.js +2 -0
- package/dist/mockImpl/index.d.ts +25 -0
- package/dist/mockImpl/index.js +98 -0
- package/dist/mockImpl/index.test.d.ts +1 -0
- package/dist/mockImpl/index.test.js +67 -0
- package/package.json +3 -3
- package/src/example.ts +6 -2
- package/src/index.test.ts +25 -2
- package/src/index.ts +32 -14
- package/src/interfaces/RabbitWrapperInterface.ts +17 -0
- package/src/mockImpl/index.test.ts +63 -0
- package/src/mockImpl/index.ts +132 -0
package/dist/example.js
CHANGED
|
@@ -10,10 +10,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const index_1 = require("./index");
|
|
13
|
-
|
|
13
|
+
process.env.RABBITMQ_SERVICE_HOST = '34.76.123.137:5672';
|
|
14
14
|
const init = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
15
|
const rabbit = new index_1.default();
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17
16
|
yield rabbit.consumeFromExchange('test-q2', 'test-e', (msg, ack) => {
|
|
18
17
|
console.log('consumeFromExchange: msg2', msg.content);
|
|
19
18
|
ack(msg);
|
|
@@ -29,5 +28,7 @@ const init = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
29
28
|
ack(msg);
|
|
30
29
|
});
|
|
31
30
|
yield rabbit.sendToQueue('test-q-2', 'hey-q');
|
|
31
|
+
const getQueueLength = yield rabbit.getQueueLength('test-q2');
|
|
32
|
+
console.log(`getQueueLength:${getQueueLength}`);
|
|
32
33
|
});
|
|
33
34
|
init();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { AmqpConnectionManager, ChannelWrapper } from 'amqp-connection-manager';
|
|
3
3
|
import { EventEmitter } from 'events';
|
|
4
|
+
import RabbitWrapperInterface from './interfaces/RabbitWrapperInterface';
|
|
4
5
|
interface ExchangesCache {
|
|
5
6
|
[key: string]: any;
|
|
6
7
|
}
|
|
7
|
-
declare class RabbitMq {
|
|
8
|
+
declare class RabbitMq implements RabbitWrapperInterface {
|
|
8
9
|
static parseMsg(msg: any): any;
|
|
9
10
|
static validateName(type: string, name: string): void;
|
|
10
11
|
PUBLISH_TIMEOUT: number;
|
|
@@ -15,12 +16,19 @@ declare class RabbitMq {
|
|
|
15
16
|
em: EventEmitter;
|
|
16
17
|
creatingConnection: boolean;
|
|
17
18
|
exchanges: ExchangesCache;
|
|
18
|
-
|
|
19
|
+
isTestEnv: boolean;
|
|
20
|
+
constructor({ isTestEnv }?: {
|
|
21
|
+
isTestEnv?: boolean | undefined;
|
|
22
|
+
});
|
|
23
|
+
private getConnectFunc;
|
|
24
|
+
private connect;
|
|
19
25
|
ack: (msg: any) => Promise<void>;
|
|
20
26
|
nack: (queue: string) => (msg: any, retries: number) => Promise<void>;
|
|
21
27
|
getConnection(): Promise<AmqpConnectionManager>;
|
|
22
28
|
assertChannel(): Promise<ChannelWrapper>;
|
|
23
29
|
assertExchange(exchangeName: string, options?: any): Promise<any>;
|
|
30
|
+
getQueueLength(queue: string): Promise<any>;
|
|
31
|
+
bindQueue(queue: string, exchange: string): Promise<any>;
|
|
24
32
|
assertQueue(queue: string, options?: any): Promise<void>;
|
|
25
33
|
consume(queue: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any): Promise<void>;
|
|
26
34
|
consumeFromExchange(queue: string, exchange: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -9,18 +9,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
/* 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 */
|
|
12
13
|
// eslint-disable-next-line max-classes-per-file
|
|
13
14
|
const bluebird = require("bluebird");
|
|
14
15
|
const amqp_connection_manager_1 = require("amqp-connection-manager");
|
|
15
16
|
const events_1 = require("events");
|
|
17
|
+
const mockImpl_1 = require("./mockImpl");
|
|
16
18
|
const rabbitError_1 = require("./rabbitError");
|
|
17
19
|
const assertExchangeFanout = (c, exchangeName) => c.assertExchange(exchangeName, 'fanout');
|
|
18
20
|
const connectionCreatedConst = 'connectionCreated';
|
|
19
21
|
class RabbitMq {
|
|
20
|
-
constructor() {
|
|
22
|
+
constructor({ isTestEnv = false } = {}) {
|
|
21
23
|
this.PUBLISH_TIMEOUT = Number(process.env.RABBITMQ_PUBLISH_TIMEOUT) || 60000;
|
|
22
24
|
this.PUBLISH_ERROR_MSG = `rabbit: publish timeout(${this.PUBLISH_TIMEOUT}ms) has pass, exchange: `;
|
|
23
25
|
this.DISCONNECT_MSG = 'rabbit: connection disconnect';
|
|
26
|
+
this.getConnectFunc = () => (this.isTestEnv ? mockImpl_1.connect : amqp_connection_manager_1.connect);
|
|
27
|
+
this.connect = (urls = []) => this.getConnectFunc()(urls);
|
|
24
28
|
this.ack = (msg) => __awaiter(this, void 0, void 0, function* () {
|
|
25
29
|
if (this.channel) {
|
|
26
30
|
yield this.channel.ack(msg);
|
|
@@ -29,7 +33,6 @@ class RabbitMq {
|
|
|
29
33
|
this.nack = (queue) => (msg, retries) => __awaiter(this, void 0, void 0, function* () {
|
|
30
34
|
if (this.channel) {
|
|
31
35
|
if (!msg.content['x-retry-count'] || msg.content['x-retry-count'] <= retries) {
|
|
32
|
-
// eslint-disable-next-line no-param-reassign
|
|
33
36
|
msg.content['x-retry-count'] = msg.content['x-retry-count'] ? msg.content['x-retry-count'] + 1 : 1;
|
|
34
37
|
yield this.sendToQueue(queue, msg.content);
|
|
35
38
|
}
|
|
@@ -46,6 +49,7 @@ class RabbitMq {
|
|
|
46
49
|
this.connection = null;
|
|
47
50
|
this.creatingConnection = false;
|
|
48
51
|
this.exchanges = {};
|
|
52
|
+
this.isTestEnv = isTestEnv;
|
|
49
53
|
}
|
|
50
54
|
static parseMsg(msg) {
|
|
51
55
|
let { content } = msg;
|
|
@@ -53,7 +57,7 @@ class RabbitMq {
|
|
|
53
57
|
try {
|
|
54
58
|
content = JSON.parse(content);
|
|
55
59
|
}
|
|
56
|
-
catch (e) { }
|
|
60
|
+
catch (e) { }
|
|
57
61
|
return Object.assign(Object.assign({}, msg), { content });
|
|
58
62
|
}
|
|
59
63
|
static validateName(type, name) {
|
|
@@ -63,19 +67,17 @@ class RabbitMq {
|
|
|
63
67
|
}
|
|
64
68
|
getConnection() {
|
|
65
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
-
// eslint-disable-next-line no-async-promise-executor
|
|
67
70
|
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
68
71
|
if (this.creatingConnection) {
|
|
69
72
|
this.em.on(connectionCreatedConst, resolve);
|
|
70
73
|
return;
|
|
71
74
|
}
|
|
72
75
|
if (this.connection !== null) {
|
|
73
|
-
// eslint-disable-next-line consistent-return
|
|
74
76
|
return this.connection;
|
|
75
77
|
}
|
|
76
78
|
this.creatingConnection = true;
|
|
77
79
|
const host = process.env.RABBITMQ_SERVICE_HOST || '';
|
|
78
|
-
const connection = yield
|
|
80
|
+
const connection = yield this.connect([`amqp://${host}`]);
|
|
79
81
|
this.connection = connection;
|
|
80
82
|
this.connection.on('disconnect', ({ err }) => console.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`));
|
|
81
83
|
this.creatingConnection = false;
|
|
@@ -86,7 +88,6 @@ class RabbitMq {
|
|
|
86
88
|
}
|
|
87
89
|
assertChannel() {
|
|
88
90
|
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
-
// eslint-disable-next-line no-async-promise-executor,consistent-return
|
|
90
91
|
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
91
92
|
if (this.channel) {
|
|
92
93
|
return resolve(this.channel);
|
|
@@ -94,7 +95,7 @@ class RabbitMq {
|
|
|
94
95
|
const connection = yield this.getConnection();
|
|
95
96
|
try {
|
|
96
97
|
if (this.channel === null) {
|
|
97
|
-
this.channel = connection.createChannel({});
|
|
98
|
+
this.channel = yield connection.createChannel({});
|
|
98
99
|
}
|
|
99
100
|
resolve(this.channel);
|
|
100
101
|
}
|
|
@@ -104,7 +105,6 @@ class RabbitMq {
|
|
|
104
105
|
}));
|
|
105
106
|
});
|
|
106
107
|
}
|
|
107
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
108
108
|
assertExchange(exchangeName, options) {
|
|
109
109
|
return __awaiter(this, void 0, void 0, function* () {
|
|
110
110
|
const channel = yield this.assertChannel();
|
|
@@ -118,7 +118,21 @@ class RabbitMq {
|
|
|
118
118
|
}));
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
|
-
|
|
121
|
+
getQueueLength(queue) {
|
|
122
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
123
|
+
RabbitMq.validateName('queue', queue);
|
|
124
|
+
const channel = yield this.assertChannel();
|
|
125
|
+
// @ts-ignore
|
|
126
|
+
return channel.checkQueue(queue);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
bindQueue(queue, exchange) {
|
|
130
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
131
|
+
const channel = yield this.assertChannel();
|
|
132
|
+
// @ts-ignore
|
|
133
|
+
return channel.bindQueue(queue, exchange, '');
|
|
134
|
+
});
|
|
135
|
+
}
|
|
122
136
|
assertQueue(queue, options) {
|
|
123
137
|
return __awaiter(this, void 0, void 0, function* () {
|
|
124
138
|
RabbitMq.validateName('queue', queue);
|
|
@@ -126,7 +140,6 @@ class RabbitMq {
|
|
|
126
140
|
return channel.addSetup((c) => c.assertQueue(queue));
|
|
127
141
|
});
|
|
128
142
|
}
|
|
129
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
130
143
|
consume(queue, callback, options) {
|
|
131
144
|
return __awaiter(this, void 0, void 0, function* () {
|
|
132
145
|
RabbitMq.validateName('queue', queue);
|
|
@@ -141,7 +154,6 @@ class RabbitMq {
|
|
|
141
154
|
}));
|
|
142
155
|
});
|
|
143
156
|
}
|
|
144
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
145
157
|
consumeFromExchange(queue, exchange, callback, options) {
|
|
146
158
|
return __awaiter(this, void 0, void 0, function* () {
|
|
147
159
|
RabbitMq.validateName('queue', queue);
|
package/dist/index.test.js
CHANGED
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment,@typescript-eslint/no-unused-vars */
|
|
12
13
|
const index_1 = require("./index");
|
|
13
|
-
// import RabbitError from './rabbitError';
|
|
14
14
|
jest.setTimeout(120000);
|
|
15
15
|
const rabbit = new index_1.default();
|
|
16
16
|
const delay = () => new Promise((resolve) => setTimeout(() => resolve(), 500));
|
|
@@ -48,7 +48,6 @@ describe('RabbitMQ', () => {
|
|
|
48
48
|
expect(err).toBeDefined();
|
|
49
49
|
}));
|
|
50
50
|
it('cant publish due timeout', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
52
51
|
// @ts-ignore
|
|
53
52
|
process.env.RABBITMQ_PUBLISH_TIMEOUT = 1;
|
|
54
53
|
const rabbit2 = new index_1.default();
|
|
@@ -61,4 +60,25 @@ describe('RabbitMQ', () => {
|
|
|
61
60
|
}
|
|
62
61
|
expect(err).toBeDefined();
|
|
63
62
|
}));
|
|
63
|
+
it('get queue length', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
|
+
const queueName = 'test-queue-length';
|
|
65
|
+
const exchangeName = 'test-e2';
|
|
66
|
+
yield rabbit.assertQueue(queueName);
|
|
67
|
+
yield rabbit.assertExchange(exchangeName);
|
|
68
|
+
yield rabbit.bindQueue(queueName, exchangeName);
|
|
69
|
+
yield rabbit.publish(exchangeName, 'hey');
|
|
70
|
+
let messageCount;
|
|
71
|
+
({ messageCount } = yield rabbit.getQueueLength(queueName));
|
|
72
|
+
expect(messageCount).toEqual(1);
|
|
73
|
+
yield rabbit.publish(exchangeName, 'hey');
|
|
74
|
+
({ messageCount } = yield rabbit.getQueueLength(queueName));
|
|
75
|
+
expect(messageCount).toEqual(2);
|
|
76
|
+
yield rabbit.consumeFromExchange(queueName, exchangeName, (msg, ack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
77
|
+
expect(msg.content).toEqual('hey');
|
|
78
|
+
ack(msg);
|
|
79
|
+
}));
|
|
80
|
+
yield delay();
|
|
81
|
+
({ messageCount } = yield rabbit.getQueueLength(queueName));
|
|
82
|
+
expect(messageCount).toEqual(0);
|
|
83
|
+
}));
|
|
64
84
|
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface RabbitWrapperInterface {
|
|
2
|
+
ack: any;
|
|
3
|
+
nack: any;
|
|
4
|
+
getConnection: any;
|
|
5
|
+
assertChannel: any;
|
|
6
|
+
assertExchange: any;
|
|
7
|
+
getQueueLength: any;
|
|
8
|
+
bindQueue: any;
|
|
9
|
+
assertQueue: any;
|
|
10
|
+
consume: any;
|
|
11
|
+
consumeFromExchange: any;
|
|
12
|
+
publish: any;
|
|
13
|
+
sendToQueue: any;
|
|
14
|
+
}
|
|
15
|
+
export default RabbitWrapperInterface;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface channel {
|
|
2
|
+
assertQueue: any;
|
|
3
|
+
assertExchange: any;
|
|
4
|
+
bindQueue: any;
|
|
5
|
+
publish: any;
|
|
6
|
+
consume: any;
|
|
7
|
+
deleteQueue: any;
|
|
8
|
+
ack: any;
|
|
9
|
+
nack: any;
|
|
10
|
+
prefetch: any;
|
|
11
|
+
on: any;
|
|
12
|
+
once: any;
|
|
13
|
+
close: any;
|
|
14
|
+
addSetup: any;
|
|
15
|
+
checkQueue: any;
|
|
16
|
+
sendToQueue: any;
|
|
17
|
+
}
|
|
18
|
+
export interface connection {
|
|
19
|
+
createChannel: any;
|
|
20
|
+
createConfirmChannel: any;
|
|
21
|
+
on: any;
|
|
22
|
+
once: any;
|
|
23
|
+
close: any;
|
|
24
|
+
}
|
|
25
|
+
export declare const connect: () => any;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.connect = void 0;
|
|
13
|
+
const Bluebird = require("bluebird");
|
|
14
|
+
let exchanges = {};
|
|
15
|
+
let queues = {};
|
|
16
|
+
const setIfUndef = (object, prop, value) => {
|
|
17
|
+
if (!object[prop]) {
|
|
18
|
+
// eslint-disable-next-line no-param-reassign
|
|
19
|
+
object[prop] = value;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
class ChannelImpl {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.assertQueue = (queue, qOptions) => new Bluebird((resolve) => {
|
|
25
|
+
setIfUndef(queues, queue, { messages: [], subscribers: [], options: qOptions });
|
|
26
|
+
return resolve();
|
|
27
|
+
});
|
|
28
|
+
this.assertExchange = (exchange, type, exchOptions = {}) => new Bluebird((resolve) => {
|
|
29
|
+
setIfUndef(exchanges, exchange, { bindings: [], options: exchOptions, type });
|
|
30
|
+
return resolve();
|
|
31
|
+
});
|
|
32
|
+
this.bindQueue = (queue, exchange, key) => new Bluebird((resolve, reject) => {
|
|
33
|
+
if (!exchanges[exchange])
|
|
34
|
+
return reject(`Bind to non-existing exchange ${exchange}`);
|
|
35
|
+
const re = `^${key.replace('.', '\\.').replace('#', '(\\w|\\.)+').replace('*', '\\w+')}$`;
|
|
36
|
+
exchanges[exchange].bindings.push({ regex: new RegExp(re), queueName: queue });
|
|
37
|
+
return resolve();
|
|
38
|
+
});
|
|
39
|
+
this.publish = (exchange, routingKey, content, props) => new Bluebird((resolve, reject) => {
|
|
40
|
+
if (!exchanges[exchange])
|
|
41
|
+
return reject(`Publish to non-existing exchange ${exchange}`);
|
|
42
|
+
const { bindings } = exchanges[exchange];
|
|
43
|
+
const matchingBindings = bindings.filter((b) => b.regex.test(routingKey));
|
|
44
|
+
matchingBindings.forEach((binding) => {
|
|
45
|
+
const subscribers = queues[binding.queueName] ? queues[binding.queueName].subscribers : [];
|
|
46
|
+
subscribers.forEach((sub) => {
|
|
47
|
+
const message = { fields: { routingKey }, properties: props, content };
|
|
48
|
+
sub(message);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
return resolve();
|
|
52
|
+
});
|
|
53
|
+
this.consume = (queue, handler) => {
|
|
54
|
+
queues[queue].subscribers.push(handler);
|
|
55
|
+
};
|
|
56
|
+
this.sendToQueue = (queue, content, routingKey = '', props = {}) => {
|
|
57
|
+
const subscribers = queues[queue] ? queues[queue].subscribers : [];
|
|
58
|
+
subscribers.forEach((sub) => {
|
|
59
|
+
const message = { fields: { routingKey }, properties: props, content };
|
|
60
|
+
sub(message);
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
this.deleteQueue = (queue) => {
|
|
64
|
+
setImmediate(() => {
|
|
65
|
+
delete queues[queue];
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
this.checkQueue = () => ({ messageCount: 0 });
|
|
69
|
+
this.ack = () => null;
|
|
70
|
+
this.nack = () => null;
|
|
71
|
+
this.prefetch = () => null;
|
|
72
|
+
this.on = () => null;
|
|
73
|
+
this.once = () => null;
|
|
74
|
+
this.close = () => Bluebird.resolve();
|
|
75
|
+
}
|
|
76
|
+
addSetup(funcToRun) {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
const val = yield funcToRun(this);
|
|
79
|
+
return val;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const createChannel = () => new Bluebird((resolve) => resolve(new ChannelImpl()));
|
|
84
|
+
exports.connect = () => new Bluebird((resolve) => {
|
|
85
|
+
const connectionImpl = {
|
|
86
|
+
createChannel,
|
|
87
|
+
createConfirmChannel: createChannel,
|
|
88
|
+
on: () => null,
|
|
89
|
+
once: () => null,
|
|
90
|
+
close: () => Bluebird.resolve(),
|
|
91
|
+
};
|
|
92
|
+
return resolve(connectionImpl);
|
|
93
|
+
});
|
|
94
|
+
const resetMock = () => {
|
|
95
|
+
queues = {};
|
|
96
|
+
exchanges = {};
|
|
97
|
+
};
|
|
98
|
+
module.exports = { connect: exports.connect, resetMock };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment,@typescript-eslint/no-unused-vars */
|
|
13
|
+
const index_1 = require("../index");
|
|
14
|
+
jest.setTimeout(120000);
|
|
15
|
+
const rabbit = new index_1.default({ isTestEnv: true });
|
|
16
|
+
describe('RabbitMQ', () => {
|
|
17
|
+
it('check exchange', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
const callback = (msg, ack) => {
|
|
19
|
+
expect(msg.content).toEqual('hey');
|
|
20
|
+
ack(msg);
|
|
21
|
+
};
|
|
22
|
+
const mockFn = jest.fn(callback);
|
|
23
|
+
yield rabbit.consumeFromExchange('test-q2', 'test-e', mockFn);
|
|
24
|
+
yield rabbit.publish('test-e', 'hey');
|
|
25
|
+
expect(mockFn).toBeCalled();
|
|
26
|
+
}));
|
|
27
|
+
it('check queue', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
+
const callback = (msg, ack) => {
|
|
29
|
+
expect(msg.content).toEqual('hey-q');
|
|
30
|
+
ack(msg);
|
|
31
|
+
};
|
|
32
|
+
const mockFn = jest.fn(callback);
|
|
33
|
+
yield rabbit.consume('test-q-2', mockFn);
|
|
34
|
+
yield rabbit.sendToQueue('test-q-2', 'hey-q');
|
|
35
|
+
expect(mockFn).toBeCalled();
|
|
36
|
+
}));
|
|
37
|
+
it('cant publish to unknown exchange', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
let err;
|
|
39
|
+
try {
|
|
40
|
+
yield rabbit.publish('', 'hey');
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
err = e;
|
|
44
|
+
}
|
|
45
|
+
expect(err).toBeDefined();
|
|
46
|
+
}));
|
|
47
|
+
it('get queue length', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
48
|
+
const queueName = 'test-queue-length';
|
|
49
|
+
const exchangeName = 'test-e2';
|
|
50
|
+
yield rabbit.assertQueue(queueName);
|
|
51
|
+
yield rabbit.assertExchange(exchangeName);
|
|
52
|
+
yield rabbit.bindQueue(queueName, exchangeName);
|
|
53
|
+
yield rabbit.publish(exchangeName, 'hey');
|
|
54
|
+
let messageCount;
|
|
55
|
+
({ messageCount } = yield rabbit.getQueueLength(queueName));
|
|
56
|
+
expect(messageCount).toEqual(0);
|
|
57
|
+
yield rabbit.publish(exchangeName, 'hey');
|
|
58
|
+
({ messageCount } = yield rabbit.getQueueLength(queueName));
|
|
59
|
+
expect(messageCount).toEqual(0);
|
|
60
|
+
yield rabbit.consumeFromExchange(queueName, exchangeName, (msg, ack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
61
|
+
expect(msg.content).toEqual('hey');
|
|
62
|
+
ack(msg);
|
|
63
|
+
}));
|
|
64
|
+
({ messageCount } = yield rabbit.getQueueLength(queueName));
|
|
65
|
+
expect(messageCount).toEqual(0);
|
|
66
|
+
}));
|
|
67
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/rabbit",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
"dev": "nodemon"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
+
"@types/amqp-connection-manager": "^2.0.10",
|
|
18
|
+
"@types/amqplib": "^0.5.16",
|
|
17
19
|
"@types/jest": "^22.0.0",
|
|
18
|
-
"@types/amqp-connection-manager": "^2.0.2",
|
|
19
|
-
"@types/amqplib": "^0.5.9",
|
|
20
20
|
"amqp-connection-manager": "^3.2.1",
|
|
21
21
|
"amqplib": "^0.6.0",
|
|
22
22
|
"bluebird": "^3.7.2",
|
package/src/example.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import RabbitMq from './index';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
process.env.RABBITMQ_SERVICE_HOST = '34.76.123.137:5672';
|
|
4
4
|
|
|
5
5
|
const init = async () => {
|
|
6
6
|
const rabbit = new RabbitMq();
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
await rabbit.consumeFromExchange('test-q2', 'test-e', (msg, ack) => {
|
|
9
9
|
console.log('consumeFromExchange: msg2', msg.content);
|
|
10
10
|
ack(msg);
|
|
@@ -21,7 +21,11 @@ const init = async () => {
|
|
|
21
21
|
console.log('consume: msg-q', msg.content);
|
|
22
22
|
ack(msg);
|
|
23
23
|
});
|
|
24
|
+
|
|
24
25
|
await rabbit.sendToQueue('test-q-2', 'hey-q');
|
|
26
|
+
|
|
27
|
+
const getQueueLength = await rabbit.getQueueLength('test-q2');
|
|
28
|
+
console.log(`getQueueLength:${getQueueLength}`);
|
|
25
29
|
};
|
|
26
30
|
|
|
27
31
|
init();
|
package/src/index.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment,@typescript-eslint/no-unused-vars */
|
|
1
2
|
import RabbitMq from './index';
|
|
2
|
-
// import RabbitError from './rabbitError';
|
|
3
3
|
|
|
4
4
|
jest.setTimeout(120000);
|
|
5
5
|
|
|
@@ -43,7 +43,6 @@ describe('RabbitMQ', () => {
|
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
it('cant publish due timeout', async () => {
|
|
46
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
47
46
|
// @ts-ignore
|
|
48
47
|
process.env.RABBITMQ_PUBLISH_TIMEOUT = 1;
|
|
49
48
|
const rabbit2 = new RabbitMq();
|
|
@@ -56,4 +55,28 @@ describe('RabbitMQ', () => {
|
|
|
56
55
|
}
|
|
57
56
|
expect(err).toBeDefined();
|
|
58
57
|
});
|
|
58
|
+
|
|
59
|
+
it('get queue length', async () => {
|
|
60
|
+
const queueName = 'test-queue-length';
|
|
61
|
+
const exchangeName = 'test-e2';
|
|
62
|
+
|
|
63
|
+
await rabbit.assertQueue(queueName);
|
|
64
|
+
await rabbit.assertExchange(exchangeName);
|
|
65
|
+
await rabbit.bindQueue(queueName, exchangeName);
|
|
66
|
+
|
|
67
|
+
await rabbit.publish(exchangeName, 'hey');
|
|
68
|
+
let messageCount: any;
|
|
69
|
+
({ messageCount } = await rabbit.getQueueLength(queueName));
|
|
70
|
+
expect(messageCount).toEqual(1);
|
|
71
|
+
await rabbit.publish(exchangeName, 'hey');
|
|
72
|
+
({ messageCount } = await rabbit.getQueueLength(queueName));
|
|
73
|
+
expect(messageCount).toEqual(2);
|
|
74
|
+
await rabbit.consumeFromExchange(queueName, exchangeName, async (msg: any, ack: any) => {
|
|
75
|
+
expect(msg.content).toEqual('hey');
|
|
76
|
+
ack(msg);
|
|
77
|
+
});
|
|
78
|
+
await delay();
|
|
79
|
+
({ messageCount } = await rabbit.getQueueLength(queueName));
|
|
80
|
+
expect(messageCount).toEqual(0);
|
|
81
|
+
});
|
|
59
82
|
});
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
/* 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 */
|
|
1
2
|
// eslint-disable-next-line max-classes-per-file
|
|
2
3
|
import * as bluebird from 'bluebird';
|
|
3
4
|
import { ConfirmChannel } from 'amqplib';
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AmqpConnectionManager, ChannelWrapper,
|
|
7
|
+
connect as connectAmqp,
|
|
8
|
+
} from 'amqp-connection-manager';
|
|
5
9
|
import { EventEmitter } from 'events';
|
|
10
|
+
import { connect as connectMock } from './mockImpl';
|
|
11
|
+
import RabbitWrapperInterface from './interfaces/RabbitWrapperInterface';
|
|
6
12
|
import RabbitError from './rabbitError';
|
|
7
13
|
|
|
8
14
|
interface ExchangesCache {
|
|
@@ -12,14 +18,14 @@ interface ExchangesCache {
|
|
|
12
18
|
const assertExchangeFanout = (c: any, exchangeName: string) => c.assertExchange(exchangeName, 'fanout');
|
|
13
19
|
|
|
14
20
|
const connectionCreatedConst = 'connectionCreated';
|
|
15
|
-
class RabbitMq {
|
|
21
|
+
class RabbitMq implements RabbitWrapperInterface {
|
|
16
22
|
static parseMsg(msg: any) {
|
|
17
23
|
let { content } = msg;
|
|
18
24
|
content = content.toString();
|
|
19
25
|
|
|
20
26
|
try {
|
|
21
27
|
content = JSON.parse(content);
|
|
22
|
-
} catch (e) { }
|
|
28
|
+
} catch (e) { }
|
|
23
29
|
|
|
24
30
|
return {
|
|
25
31
|
...msg,
|
|
@@ -49,14 +55,21 @@ class RabbitMq {
|
|
|
49
55
|
|
|
50
56
|
exchanges: ExchangesCache;
|
|
51
57
|
|
|
52
|
-
|
|
58
|
+
isTestEnv: boolean;
|
|
59
|
+
|
|
60
|
+
constructor({ isTestEnv = false } = {}) {
|
|
53
61
|
this.em = new EventEmitter();
|
|
54
62
|
this.channel = null;
|
|
55
63
|
this.connection = null;
|
|
56
64
|
this.creatingConnection = false;
|
|
57
65
|
this.exchanges = {};
|
|
66
|
+
this.isTestEnv = isTestEnv;
|
|
58
67
|
}
|
|
59
68
|
|
|
69
|
+
private getConnectFunc = () => (this.isTestEnv ? connectMock : connectAmqp)
|
|
70
|
+
|
|
71
|
+
private connect = (urls:any[] = []) => this.getConnectFunc()(urls);
|
|
72
|
+
|
|
60
73
|
public ack = async (msg: any) => {
|
|
61
74
|
if (this.channel) {
|
|
62
75
|
await this.channel.ack(msg);
|
|
@@ -66,7 +79,6 @@ class RabbitMq {
|
|
|
66
79
|
public nack = (queue: string) => async (msg: any, retries: number) => {
|
|
67
80
|
if (this.channel) {
|
|
68
81
|
if (!msg.content['x-retry-count'] || msg.content['x-retry-count'] <= retries) {
|
|
69
|
-
// eslint-disable-next-line no-param-reassign
|
|
70
82
|
msg.content['x-retry-count'] = msg.content['x-retry-count'] ? msg.content['x-retry-count'] + 1 : 1;
|
|
71
83
|
await this.sendToQueue(queue, msg.content);
|
|
72
84
|
} else {
|
|
@@ -79,19 +91,17 @@ class RabbitMq {
|
|
|
79
91
|
}
|
|
80
92
|
|
|
81
93
|
async getConnection() {
|
|
82
|
-
// eslint-disable-next-line no-async-promise-executor
|
|
83
94
|
return new Promise<AmqpConnectionManager>(async (resolve) => {
|
|
84
95
|
if (this.creatingConnection) {
|
|
85
96
|
this.em.on(connectionCreatedConst, resolve);
|
|
86
97
|
return;
|
|
87
98
|
}
|
|
88
99
|
if (this.connection !== null) {
|
|
89
|
-
// eslint-disable-next-line consistent-return
|
|
90
100
|
return this.connection;
|
|
91
101
|
}
|
|
92
102
|
this.creatingConnection = true;
|
|
93
103
|
const host: string = process.env.RABBITMQ_SERVICE_HOST || '';
|
|
94
|
-
const connection: AmqpConnectionManager = await connect([`amqp://${host}`]);
|
|
104
|
+
const connection: AmqpConnectionManager = await this.connect([`amqp://${host}`]);
|
|
95
105
|
this.connection = connection;
|
|
96
106
|
this.connection.on('disconnect',
|
|
97
107
|
({ err }) => console.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`));
|
|
@@ -102,7 +112,6 @@ class RabbitMq {
|
|
|
102
112
|
}
|
|
103
113
|
|
|
104
114
|
async assertChannel() {
|
|
105
|
-
// eslint-disable-next-line no-async-promise-executor,consistent-return
|
|
106
115
|
return new Promise<ChannelWrapper>(async (resolve, reject) => {
|
|
107
116
|
if (this.channel) {
|
|
108
117
|
return resolve(this.channel);
|
|
@@ -112,7 +121,7 @@ class RabbitMq {
|
|
|
112
121
|
|
|
113
122
|
try {
|
|
114
123
|
if (this.channel === null) {
|
|
115
|
-
this.channel = connection.createChannel({});
|
|
124
|
+
this.channel = await connection.createChannel({});
|
|
116
125
|
}
|
|
117
126
|
resolve(this.channel);
|
|
118
127
|
} catch (e) {
|
|
@@ -121,7 +130,6 @@ class RabbitMq {
|
|
|
121
130
|
});
|
|
122
131
|
}
|
|
123
132
|
|
|
124
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
125
133
|
async assertExchange(exchangeName: string, options?: any) {
|
|
126
134
|
const channel: ChannelWrapper = await this.assertChannel();
|
|
127
135
|
if (this.exchanges[exchangeName]) {
|
|
@@ -134,14 +142,25 @@ class RabbitMq {
|
|
|
134
142
|
});
|
|
135
143
|
}
|
|
136
144
|
|
|
137
|
-
|
|
145
|
+
async getQueueLength(queue: string) {
|
|
146
|
+
RabbitMq.validateName('queue', queue);
|
|
147
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
148
|
+
// @ts-ignore
|
|
149
|
+
return channel.checkQueue(queue);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async bindQueue(queue: string, exchange: string) {
|
|
153
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
154
|
+
// @ts-ignore
|
|
155
|
+
return channel.bindQueue(queue, exchange, '');
|
|
156
|
+
}
|
|
157
|
+
|
|
138
158
|
async assertQueue(queue: string, options?: any) {
|
|
139
159
|
RabbitMq.validateName('queue', queue);
|
|
140
160
|
const channel: ChannelWrapper = await this.assertChannel();
|
|
141
161
|
return channel.addSetup((c: ConfirmChannel) => c.assertQueue(queue));
|
|
142
162
|
}
|
|
143
163
|
|
|
144
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
145
164
|
async consume(queue: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any) {
|
|
146
165
|
RabbitMq.validateName('queue', queue);
|
|
147
166
|
const { limit } = (options && options.limit) ? options : { limit: 1 };
|
|
@@ -155,7 +174,6 @@ class RabbitMq {
|
|
|
155
174
|
});
|
|
156
175
|
}
|
|
157
176
|
|
|
158
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
159
177
|
async consumeFromExchange(queue: string, exchange: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any) {
|
|
160
178
|
RabbitMq.validateName('queue', queue);
|
|
161
179
|
RabbitMq.validateName('exchange', exchange);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface RabbitWrapperInterface {
|
|
2
|
+
ack:any;
|
|
3
|
+
nack: any;
|
|
4
|
+
getConnection: any;
|
|
5
|
+
assertChannel: any;
|
|
6
|
+
assertExchange: any;
|
|
7
|
+
getQueueLength: any;
|
|
8
|
+
bindQueue: any;
|
|
9
|
+
assertQueue: any;
|
|
10
|
+
consume: any;
|
|
11
|
+
consumeFromExchange: any;
|
|
12
|
+
publish: any;
|
|
13
|
+
sendToQueue: any;
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default RabbitWrapperInterface;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment,@typescript-eslint/no-unused-vars */
|
|
2
|
+
import RabbitMq from '../index';
|
|
3
|
+
|
|
4
|
+
jest.setTimeout(120000);
|
|
5
|
+
|
|
6
|
+
const rabbit = new RabbitMq({ isTestEnv: true });
|
|
7
|
+
|
|
8
|
+
describe('RabbitMQ', () => {
|
|
9
|
+
it('check exchange', async () => {
|
|
10
|
+
const callback = (msg: any, ack: any) => {
|
|
11
|
+
expect(msg.content).toEqual('hey');
|
|
12
|
+
ack(msg);
|
|
13
|
+
};
|
|
14
|
+
const mockFn = jest.fn(callback);
|
|
15
|
+
await rabbit.consumeFromExchange('test-q2', 'test-e', mockFn);
|
|
16
|
+
await rabbit.publish('test-e', 'hey');
|
|
17
|
+
expect(mockFn).toBeCalled();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('check queue', async () => {
|
|
21
|
+
const callback = (msg: any, ack: any) => {
|
|
22
|
+
expect(msg.content).toEqual('hey-q');
|
|
23
|
+
ack(msg);
|
|
24
|
+
};
|
|
25
|
+
const mockFn = jest.fn(callback);
|
|
26
|
+
await rabbit.consume('test-q-2', mockFn);
|
|
27
|
+
await rabbit.sendToQueue('test-q-2', 'hey-q');
|
|
28
|
+
expect(mockFn).toBeCalled();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('cant publish to unknown exchange', async () => {
|
|
32
|
+
let err;
|
|
33
|
+
try {
|
|
34
|
+
await rabbit.publish('', 'hey');
|
|
35
|
+
} catch (e) {
|
|
36
|
+
err = e;
|
|
37
|
+
}
|
|
38
|
+
expect(err).toBeDefined();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('get queue length', async () => {
|
|
42
|
+
const queueName = 'test-queue-length';
|
|
43
|
+
const exchangeName = 'test-e2';
|
|
44
|
+
|
|
45
|
+
await rabbit.assertQueue(queueName);
|
|
46
|
+
await rabbit.assertExchange(exchangeName);
|
|
47
|
+
await rabbit.bindQueue(queueName, exchangeName);
|
|
48
|
+
|
|
49
|
+
await rabbit.publish(exchangeName, 'hey');
|
|
50
|
+
let messageCount: any;
|
|
51
|
+
({ messageCount } = await rabbit.getQueueLength(queueName));
|
|
52
|
+
expect(messageCount).toEqual(0);
|
|
53
|
+
await rabbit.publish(exchangeName, 'hey');
|
|
54
|
+
({ messageCount } = await rabbit.getQueueLength(queueName));
|
|
55
|
+
expect(messageCount).toEqual(0);
|
|
56
|
+
await rabbit.consumeFromExchange(queueName, exchangeName, async (msg: any, ack: any) => {
|
|
57
|
+
expect(msg.content).toEqual('hey');
|
|
58
|
+
ack(msg);
|
|
59
|
+
});
|
|
60
|
+
({ messageCount } = await rabbit.getQueueLength(queueName));
|
|
61
|
+
expect(messageCount).toEqual(0);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as Bluebird from 'bluebird';
|
|
2
|
+
|
|
3
|
+
let exchanges: any = {};
|
|
4
|
+
let queues: any = {};
|
|
5
|
+
|
|
6
|
+
export interface channel {
|
|
7
|
+
assertQueue: any;
|
|
8
|
+
assertExchange: any;
|
|
9
|
+
bindQueue: any;
|
|
10
|
+
publish: any;
|
|
11
|
+
consume: any;
|
|
12
|
+
deleteQueue: any;
|
|
13
|
+
ack: any;
|
|
14
|
+
nack: any;
|
|
15
|
+
prefetch: any;
|
|
16
|
+
on: any;
|
|
17
|
+
once: any;
|
|
18
|
+
close: any;
|
|
19
|
+
addSetup: any;
|
|
20
|
+
checkQueue: any;
|
|
21
|
+
sendToQueue: any;
|
|
22
|
+
}
|
|
23
|
+
export interface connection {
|
|
24
|
+
createChannel: any;
|
|
25
|
+
createConfirmChannel: any;
|
|
26
|
+
on: any;
|
|
27
|
+
once: any;
|
|
28
|
+
close: any;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const setIfUndef = (object: any, prop: any, value: any) => {
|
|
32
|
+
if (!object[prop]) {
|
|
33
|
+
// eslint-disable-next-line no-param-reassign
|
|
34
|
+
object[prop] = value;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
class ChannelImpl implements channel {
|
|
39
|
+
public assertQueue = (queue: any, qOptions: any) => new Bluebird((resolve: () => any) => {
|
|
40
|
+
setIfUndef(queues, queue, { messages: [], subscribers: [], options: qOptions });
|
|
41
|
+
return resolve();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
public assertExchange = (exchange: any, type: any, exchOptions: any = {}) => new Bluebird((resolve: () => any) => {
|
|
45
|
+
setIfUndef(exchanges, exchange, { bindings: [], options: exchOptions, type });
|
|
46
|
+
|
|
47
|
+
return resolve();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
public bindQueue = (queue: any, exchange: string, key: string) => new Bluebird((resolve: () => any, reject: (arg0: string) => any) => {
|
|
51
|
+
if (!exchanges[exchange]) return reject(`Bind to non-existing exchange ${exchange}`);
|
|
52
|
+
|
|
53
|
+
const re = `^${key.replace('.', '\\.').replace('#', '(\\w|\\.)+').replace('*', '\\w+')}$`;
|
|
54
|
+
exchanges[exchange].bindings.push({ regex: new RegExp(re), queueName: queue });
|
|
55
|
+
|
|
56
|
+
return resolve();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
public publish = (exchange: string, routingKey: any, content: any, props: any) => new Bluebird((resolve: () => any, reject: (arg0: string) => any) => {
|
|
60
|
+
if (!exchanges[exchange]) return reject(`Publish to non-existing exchange ${exchange}`);
|
|
61
|
+
|
|
62
|
+
const { bindings } = exchanges[exchange];
|
|
63
|
+
const matchingBindings = bindings.filter((b: any) => b.regex.test(routingKey));
|
|
64
|
+
|
|
65
|
+
matchingBindings.forEach((binding: { queueName: string | number; }) => {
|
|
66
|
+
const subscribers = queues[binding.queueName] ? queues[binding.queueName].subscribers : [];
|
|
67
|
+
subscribers.forEach((sub: (arg0: { fields: { routingKey: any; }; properties: any; content: any; }) => void) => {
|
|
68
|
+
const message = { fields: { routingKey }, properties: props, content };
|
|
69
|
+
sub(message);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
return resolve();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
public consume = (queue: string | number, handler: any) => {
|
|
77
|
+
queues[queue].subscribers.push(handler);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
public sendToQueue = (queue: string, content: any, routingKey = '', props: any = {}) => {
|
|
81
|
+
const subscribers = queues[queue] ? queues[queue].subscribers : [];
|
|
82
|
+
subscribers.forEach((sub: (arg0: { fields: { routingKey: any; }; properties: any; content: any; }) => void) => {
|
|
83
|
+
const message = { fields: { routingKey }, properties: props, content };
|
|
84
|
+
sub(message);
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
public deleteQueue = (queue: string | number) => {
|
|
89
|
+
setImmediate(() => {
|
|
90
|
+
delete queues[queue];
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
public async addSetup(funcToRun: any) {
|
|
95
|
+
const val = await funcToRun(this);
|
|
96
|
+
return val;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public checkQueue = () => ({ messageCount: 0 });
|
|
100
|
+
|
|
101
|
+
public ack = () => null;
|
|
102
|
+
|
|
103
|
+
public nack = () => null;
|
|
104
|
+
|
|
105
|
+
public prefetch = () => null;
|
|
106
|
+
|
|
107
|
+
public on = () => null;
|
|
108
|
+
|
|
109
|
+
public once = () => null;
|
|
110
|
+
|
|
111
|
+
public close = () => Bluebird.resolve();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const createChannel = () => new Bluebird((resolve: any) => resolve(new ChannelImpl()));
|
|
115
|
+
export const connect = (): any => new Bluebird((resolve: any) => {
|
|
116
|
+
const connectionImpl: connection = {
|
|
117
|
+
createChannel,
|
|
118
|
+
createConfirmChannel: createChannel,
|
|
119
|
+
on: () => null,
|
|
120
|
+
once: () => null,
|
|
121
|
+
close: () => Bluebird.resolve(),
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
return resolve(connectionImpl);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const resetMock = () => {
|
|
128
|
+
queues = {};
|
|
129
|
+
exchanges = {};
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
module.exports = { connect, resetMock };
|