@opra/rabbitmq 1.15.1 → 1.16.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.
- package/cjs/rabbitmq-adapter.js +50 -51
- package/esm/rabbitmq-adapter.js +50 -51
- package/package.json +4 -3
- package/types/rabbitmq-adapter.d.ts +8 -5
- package/types/rabbitmq-context.d.ts +5 -5
package/cjs/rabbitmq-adapter.js
CHANGED
|
@@ -6,7 +6,7 @@ const node_zlib_1 = tslib_1.__importDefault(require("node:zlib"));
|
|
|
6
6
|
const type_is_1 = tslib_1.__importDefault(require("@browsery/type-is"));
|
|
7
7
|
const common_1 = require("@opra/common");
|
|
8
8
|
const core_1 = require("@opra/core");
|
|
9
|
-
const
|
|
9
|
+
const amqp_connection_manager_1 = require("amqp-connection-manager");
|
|
10
10
|
const content_type_1 = require("content-type");
|
|
11
11
|
const iconv_lite_1 = tslib_1.__importDefault(require("iconv-lite"));
|
|
12
12
|
const util_1 = require("util");
|
|
@@ -34,7 +34,6 @@ class RabbitmqAdapter extends core_1.PlatformAdapter {
|
|
|
34
34
|
constructor(document, config) {
|
|
35
35
|
super(config);
|
|
36
36
|
this._controllerInstances = new Map();
|
|
37
|
-
this._connections = [];
|
|
38
37
|
this._status = 'idle';
|
|
39
38
|
this.protocol = 'rpc';
|
|
40
39
|
this.platform = RabbitmqAdapter.PlatformName;
|
|
@@ -102,54 +101,54 @@ class RabbitmqAdapter extends core_1.PlatformAdapter {
|
|
|
102
101
|
handlerArgs.push(args);
|
|
103
102
|
}
|
|
104
103
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
: connectionOptions) +
|
|
113
|
-
')',
|
|
114
|
-
// @ts-ignore
|
|
115
|
-
e);
|
|
116
|
-
});
|
|
117
|
-
this._connections.push(connection);
|
|
118
|
-
const hostname = typeof connectionOptions === 'object'
|
|
119
|
-
? connectionOptions.hostname
|
|
120
|
-
: connectionOptions;
|
|
121
|
-
this.logger?.info?.(`Connected to ${hostname}`);
|
|
122
|
-
/** Subscribe to channels */
|
|
123
|
-
for (const args of handlerArgs) {
|
|
124
|
-
/** Create channel per operation */
|
|
125
|
-
const channel = await connection.createChannel();
|
|
126
|
-
for (const topic of args.topics) {
|
|
127
|
-
const opts = this._config.queues?.[topic];
|
|
128
|
-
if (opts)
|
|
129
|
-
await channel.assertQueue(topic, opts);
|
|
104
|
+
const connectionOptions = typeof this._config.connection === 'string'
|
|
105
|
+
? {
|
|
106
|
+
urls: [this._config.connection],
|
|
107
|
+
}
|
|
108
|
+
: Array.isArray(this._config.connection)
|
|
109
|
+
? {
|
|
110
|
+
urls: this._config.connection,
|
|
130
111
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
112
|
+
: this._config.connection;
|
|
113
|
+
this._client = new amqp_connection_manager_1.AmqpConnectionManagerClass(connectionOptions.urls, connectionOptions);
|
|
114
|
+
this._client.connect().catch(e => {
|
|
115
|
+
e.message =
|
|
116
|
+
'Unable to connect to RabbitMQ server at ' +
|
|
117
|
+
connectionOptions.urls +
|
|
118
|
+
'. ' +
|
|
119
|
+
e.message;
|
|
120
|
+
throw e;
|
|
121
|
+
});
|
|
122
|
+
this.logger?.info?.(`Connected RabbitMQ at ${connectionOptions.urls}`);
|
|
123
|
+
for (const args of handlerArgs) {
|
|
124
|
+
/** Create channel per operation */
|
|
125
|
+
const channel = this._client.createChannel();
|
|
126
|
+
for (const topic of args.topics) {
|
|
127
|
+
const opts = this._config.queues?.[topic];
|
|
128
|
+
if (opts)
|
|
129
|
+
await channel.assertQueue(topic, opts);
|
|
130
|
+
}
|
|
131
|
+
for (const topic of args.topics) {
|
|
132
|
+
await channel.assertQueue(topic);
|
|
133
|
+
await channel
|
|
134
|
+
.consume(topic, async (msg) => {
|
|
135
|
+
if (!msg)
|
|
136
|
+
return;
|
|
137
|
+
await this.emitAsync('message', msg, topic).catch(noOp);
|
|
138
|
+
try {
|
|
139
|
+
await args.handler(channel, topic, msg);
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
148
142
|
this._emitError(e);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
/** Consume options */
|
|
146
|
+
args.operationConfig.consumer)
|
|
147
|
+
.catch(e => {
|
|
148
|
+
this._emitError(e);
|
|
149
|
+
throw e;
|
|
150
|
+
});
|
|
151
|
+
this.logger?.info?.(`Subscribed to topic${args.topics.length > 1 ? 's' : ''} "${args.topics}"`);
|
|
153
152
|
}
|
|
154
153
|
}
|
|
155
154
|
this._status = 'started';
|
|
@@ -163,8 +162,8 @@ class RabbitmqAdapter extends core_1.PlatformAdapter {
|
|
|
163
162
|
* Closes all connections and stops the service
|
|
164
163
|
*/
|
|
165
164
|
async close() {
|
|
166
|
-
await
|
|
167
|
-
this.
|
|
165
|
+
await this._client?.close();
|
|
166
|
+
this._client = undefined;
|
|
168
167
|
this._controllerInstances.clear();
|
|
169
168
|
this._status = 'idle';
|
|
170
169
|
}
|
|
@@ -187,7 +186,7 @@ class RabbitmqAdapter extends core_1.PlatformAdapter {
|
|
|
187
186
|
return;
|
|
188
187
|
const operationConfig = {
|
|
189
188
|
consumer: {
|
|
190
|
-
noAck:
|
|
189
|
+
noAck: true,
|
|
191
190
|
},
|
|
192
191
|
};
|
|
193
192
|
if (this._config.defaults) {
|
package/esm/rabbitmq-adapter.js
CHANGED
|
@@ -2,7 +2,7 @@ import zlib from 'node:zlib';
|
|
|
2
2
|
import typeIs from '@browsery/type-is';
|
|
3
3
|
import { OpraException, RPC_CONTROLLER_METADATA, RpcApi, } from '@opra/common';
|
|
4
4
|
import { kAssetCache, PlatformAdapter } from '@opra/core';
|
|
5
|
-
import
|
|
5
|
+
import { AmqpConnectionManagerClass, } from 'amqp-connection-manager';
|
|
6
6
|
import { parse as parseContentType } from 'content-type';
|
|
7
7
|
import iconv from 'iconv-lite';
|
|
8
8
|
import { promisify } from 'util';
|
|
@@ -30,7 +30,6 @@ export class RabbitmqAdapter extends PlatformAdapter {
|
|
|
30
30
|
constructor(document, config) {
|
|
31
31
|
super(config);
|
|
32
32
|
this._controllerInstances = new Map();
|
|
33
|
-
this._connections = [];
|
|
34
33
|
this._status = 'idle';
|
|
35
34
|
this.protocol = 'rpc';
|
|
36
35
|
this.platform = RabbitmqAdapter.PlatformName;
|
|
@@ -98,54 +97,54 @@ export class RabbitmqAdapter extends PlatformAdapter {
|
|
|
98
97
|
handlerArgs.push(args);
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
: connectionOptions) +
|
|
109
|
-
')',
|
|
110
|
-
// @ts-ignore
|
|
111
|
-
e);
|
|
112
|
-
});
|
|
113
|
-
this._connections.push(connection);
|
|
114
|
-
const hostname = typeof connectionOptions === 'object'
|
|
115
|
-
? connectionOptions.hostname
|
|
116
|
-
: connectionOptions;
|
|
117
|
-
this.logger?.info?.(`Connected to ${hostname}`);
|
|
118
|
-
/** Subscribe to channels */
|
|
119
|
-
for (const args of handlerArgs) {
|
|
120
|
-
/** Create channel per operation */
|
|
121
|
-
const channel = await connection.createChannel();
|
|
122
|
-
for (const topic of args.topics) {
|
|
123
|
-
const opts = this._config.queues?.[topic];
|
|
124
|
-
if (opts)
|
|
125
|
-
await channel.assertQueue(topic, opts);
|
|
100
|
+
const connectionOptions = typeof this._config.connection === 'string'
|
|
101
|
+
? {
|
|
102
|
+
urls: [this._config.connection],
|
|
103
|
+
}
|
|
104
|
+
: Array.isArray(this._config.connection)
|
|
105
|
+
? {
|
|
106
|
+
urls: this._config.connection,
|
|
126
107
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
108
|
+
: this._config.connection;
|
|
109
|
+
this._client = new AmqpConnectionManagerClass(connectionOptions.urls, connectionOptions);
|
|
110
|
+
this._client.connect().catch(e => {
|
|
111
|
+
e.message =
|
|
112
|
+
'Unable to connect to RabbitMQ server at ' +
|
|
113
|
+
connectionOptions.urls +
|
|
114
|
+
'. ' +
|
|
115
|
+
e.message;
|
|
116
|
+
throw e;
|
|
117
|
+
});
|
|
118
|
+
this.logger?.info?.(`Connected RabbitMQ at ${connectionOptions.urls}`);
|
|
119
|
+
for (const args of handlerArgs) {
|
|
120
|
+
/** Create channel per operation */
|
|
121
|
+
const channel = this._client.createChannel();
|
|
122
|
+
for (const topic of args.topics) {
|
|
123
|
+
const opts = this._config.queues?.[topic];
|
|
124
|
+
if (opts)
|
|
125
|
+
await channel.assertQueue(topic, opts);
|
|
126
|
+
}
|
|
127
|
+
for (const topic of args.topics) {
|
|
128
|
+
await channel.assertQueue(topic);
|
|
129
|
+
await channel
|
|
130
|
+
.consume(topic, async (msg) => {
|
|
131
|
+
if (!msg)
|
|
132
|
+
return;
|
|
133
|
+
await this.emitAsync('message', msg, topic).catch(noOp);
|
|
134
|
+
try {
|
|
135
|
+
await args.handler(channel, topic, msg);
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
144
138
|
this._emitError(e);
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
/** Consume options */
|
|
142
|
+
args.operationConfig.consumer)
|
|
143
|
+
.catch(e => {
|
|
144
|
+
this._emitError(e);
|
|
145
|
+
throw e;
|
|
146
|
+
});
|
|
147
|
+
this.logger?.info?.(`Subscribed to topic${args.topics.length > 1 ? 's' : ''} "${args.topics}"`);
|
|
149
148
|
}
|
|
150
149
|
}
|
|
151
150
|
this._status = 'started';
|
|
@@ -159,8 +158,8 @@ export class RabbitmqAdapter extends PlatformAdapter {
|
|
|
159
158
|
* Closes all connections and stops the service
|
|
160
159
|
*/
|
|
161
160
|
async close() {
|
|
162
|
-
await
|
|
163
|
-
this.
|
|
161
|
+
await this._client?.close();
|
|
162
|
+
this._client = undefined;
|
|
164
163
|
this._controllerInstances.clear();
|
|
165
164
|
this._status = 'idle';
|
|
166
165
|
}
|
|
@@ -183,7 +182,7 @@ export class RabbitmqAdapter extends PlatformAdapter {
|
|
|
183
182
|
return;
|
|
184
183
|
const operationConfig = {
|
|
185
184
|
consumer: {
|
|
186
|
-
noAck:
|
|
185
|
+
noAck: true,
|
|
187
186
|
},
|
|
188
187
|
};
|
|
189
188
|
if (this._config.defaults) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/rabbitmq",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "Opra RabbitMQ package",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
"valgen": "^5.15.0"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"@opra/common": "^1.
|
|
17
|
-
"@opra/core": "^1.
|
|
16
|
+
"@opra/common": "^1.16.0",
|
|
17
|
+
"@opra/core": "^1.16.0",
|
|
18
|
+
"amqp-connection-manager": "^4.1.14",
|
|
18
19
|
"amqplib": "^0.10.7"
|
|
19
20
|
},
|
|
20
21
|
"type": "module",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ApiDocument, OpraException, OpraSchema, RpcApi, RpcController, RpcOperation } from '@opra/common';
|
|
2
2
|
import { PlatformAdapter } from '@opra/core';
|
|
3
|
-
import
|
|
3
|
+
import { type AmqpConnectionManager, type AmqpConnectionManagerOptions, type ChannelWrapper, type ConnectionUrl } from 'amqp-connection-manager';
|
|
4
|
+
import amqplib from 'amqplib';
|
|
4
5
|
import { ConsumeMessage } from 'amqplib/properties';
|
|
5
6
|
import { RabbitmqContext } from './rabbitmq-context.js';
|
|
6
7
|
export interface OperationConfig {
|
|
@@ -12,7 +13,7 @@ interface HandlerArguments {
|
|
|
12
13
|
instance: any;
|
|
13
14
|
operation: RpcOperation;
|
|
14
15
|
operationConfig: OperationConfig;
|
|
15
|
-
handler: (channel:
|
|
16
|
+
handler: (channel: ChannelWrapper, queue: string, msg: ConsumeMessage | null) => void | Promise<void>;
|
|
16
17
|
topics: string[];
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
@@ -23,7 +24,7 @@ export declare class RabbitmqAdapter extends PlatformAdapter<RabbitmqAdapter.Eve
|
|
|
23
24
|
static readonly PlatformName = "rabbitmq";
|
|
24
25
|
protected _config: RabbitmqAdapter.Config;
|
|
25
26
|
protected _controllerInstances: Map<RpcController, any>;
|
|
26
|
-
protected
|
|
27
|
+
protected _client?: AmqpConnectionManager;
|
|
27
28
|
protected _status: RabbitmqAdapter.Status;
|
|
28
29
|
readonly protocol: OpraSchema.Transport;
|
|
29
30
|
readonly platform = "rabbitmq";
|
|
@@ -71,9 +72,11 @@ export declare class RabbitmqAdapter extends PlatformAdapter<RabbitmqAdapter.Eve
|
|
|
71
72
|
export declare namespace RabbitmqAdapter {
|
|
72
73
|
type NextCallback = () => Promise<any>;
|
|
73
74
|
type Status = 'idle' | 'starting' | 'started';
|
|
74
|
-
|
|
75
|
+
interface ConnectionOptions extends AmqpConnectionManagerOptions {
|
|
76
|
+
urls?: ConnectionUrl[];
|
|
77
|
+
}
|
|
75
78
|
interface Config extends PlatformAdapter.Options {
|
|
76
|
-
connection:
|
|
79
|
+
connection: string | string[] | ConnectionOptions;
|
|
77
80
|
queues?: Record<string, amqplib.Options.AssertQueue>;
|
|
78
81
|
defaults?: {
|
|
79
82
|
consumer?: amqplib.Options.Consume;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { OpraSchema, RpcController, RpcOperation } from '@opra/common';
|
|
2
2
|
import { ExecutionContext } from '@opra/core';
|
|
3
|
-
import type {
|
|
3
|
+
import type { ChannelWrapper } from 'amqp-connection-manager';
|
|
4
4
|
import type { ConsumeMessage } from 'amqplib/properties';
|
|
5
5
|
import type { AsyncEventEmitter } from 'node-events-async';
|
|
6
6
|
import type { RabbitmqAdapter } from './rabbitmq-adapter';
|
|
@@ -18,7 +18,7 @@ export declare class RabbitmqContext extends ExecutionContext implements AsyncEv
|
|
|
18
18
|
readonly operation?: RpcOperation;
|
|
19
19
|
readonly operationHandler?: Function;
|
|
20
20
|
readonly queue: string;
|
|
21
|
-
readonly channel:
|
|
21
|
+
readonly channel: ChannelWrapper;
|
|
22
22
|
readonly message: ConsumeMessage;
|
|
23
23
|
readonly content: any;
|
|
24
24
|
readonly headers: Record<string, any>;
|
|
@@ -27,15 +27,15 @@ export declare class RabbitmqContext extends ExecutionContext implements AsyncEv
|
|
|
27
27
|
* @param init the context options
|
|
28
28
|
*/
|
|
29
29
|
constructor(init: RabbitmqContext.Initiator);
|
|
30
|
-
get properties(): import("amqplib").MessageProperties;
|
|
31
|
-
get fields(): import("amqplib").ConsumeMessageFields;
|
|
30
|
+
get properties(): import("amqplib/properties").MessageProperties;
|
|
31
|
+
get fields(): import("amqplib/properties").ConsumeMessageFields;
|
|
32
32
|
ack(): void;
|
|
33
33
|
nack(): void;
|
|
34
34
|
}
|
|
35
35
|
export declare namespace RabbitmqContext {
|
|
36
36
|
interface Initiator extends Omit<ExecutionContext.Initiator, 'document' | 'protocol' | 'documentNode'> {
|
|
37
37
|
adapter: RabbitmqAdapter;
|
|
38
|
-
channel:
|
|
38
|
+
channel: ChannelWrapper;
|
|
39
39
|
controller?: RpcController;
|
|
40
40
|
controllerInstance?: any;
|
|
41
41
|
operation?: RpcOperation;
|