runmq 1.3.0 → 1.4.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/README.md +20 -2
- package/dist/index.cjs +376 -161
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -1
- package/dist/index.d.ts +27 -1
- package/dist/index.js +376 -161
- package/dist/index.js.map +1 -1
- package/package.json +9 -3
package/dist/index.cjs
CHANGED
|
@@ -60,8 +60,8 @@ var RunMQException = class extends Error {
|
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
// src/core/clients/
|
|
64
|
-
var
|
|
63
|
+
// src/core/clients/AmqplibClientAdapter.ts
|
|
64
|
+
var import_amqplib = __toESM(require("amqplib"), 1);
|
|
65
65
|
|
|
66
66
|
// src/core/exceptions/Exceptions.ts
|
|
67
67
|
var Exceptions = class {
|
|
@@ -73,8 +73,8 @@ Exceptions.INVALID_MESSAGE_FORMAT = "MESSAGE_SHOULD_BE_VALID_RECORD";
|
|
|
73
73
|
Exceptions.UNSUPPORTED_SCHEMA = "UNSUPPORTED_SCHEMA";
|
|
74
74
|
Exceptions.FAILURE_TO_DEFINE_TTL_POLICY = "FAILURE_TO_DEFINE_TTL_POLICY";
|
|
75
75
|
|
|
76
|
-
// src/core/clients/
|
|
77
|
-
var
|
|
76
|
+
// src/core/clients/AmqplibChannel.ts
|
|
77
|
+
var AmqplibChannel = class {
|
|
78
78
|
constructor(channel) {
|
|
79
79
|
this.channel = channel;
|
|
80
80
|
}
|
|
@@ -84,8 +84,7 @@ var RabbitMQClientChannel = class {
|
|
|
84
84
|
if (options == null ? void 0 : options.deadLetterRoutingKey) args["x-dead-letter-routing-key"] = options.deadLetterRoutingKey;
|
|
85
85
|
if (options == null ? void 0 : options.messageTtl) args["x-message-ttl"] = options.messageTtl;
|
|
86
86
|
if (options == null ? void 0 : options.arguments) Object.assign(args, options.arguments);
|
|
87
|
-
const result = await this.channel.
|
|
88
|
-
queue,
|
|
87
|
+
const result = await this.channel.assertQueue(queue, {
|
|
89
88
|
durable: options == null ? void 0 : options.durable,
|
|
90
89
|
exclusive: options == null ? void 0 : options.exclusive,
|
|
91
90
|
autoDelete: options == null ? void 0 : options.autoDelete,
|
|
@@ -98,10 +97,7 @@ var RabbitMQClientChannel = class {
|
|
|
98
97
|
};
|
|
99
98
|
}
|
|
100
99
|
async checkQueue(queue) {
|
|
101
|
-
const result = await this.channel.
|
|
102
|
-
queue,
|
|
103
|
-
passive: true
|
|
104
|
-
});
|
|
100
|
+
const result = await this.channel.checkQueue(queue);
|
|
105
101
|
return {
|
|
106
102
|
queue: result.queue,
|
|
107
103
|
messageCount: result.messageCount,
|
|
@@ -109,8 +105,7 @@ var RabbitMQClientChannel = class {
|
|
|
109
105
|
};
|
|
110
106
|
}
|
|
111
107
|
async deleteQueue(queue, options) {
|
|
112
|
-
const result = await this.channel.
|
|
113
|
-
queue,
|
|
108
|
+
const result = await this.channel.deleteQueue(queue, {
|
|
114
109
|
ifUnused: options == null ? void 0 : options.ifUnused,
|
|
115
110
|
ifEmpty: options == null ? void 0 : options.ifEmpty
|
|
116
111
|
});
|
|
@@ -122,9 +117,7 @@ var RabbitMQClientChannel = class {
|
|
|
122
117
|
const args = {};
|
|
123
118
|
if (options == null ? void 0 : options.alternateExchange) args["alternate-exchange"] = options.alternateExchange;
|
|
124
119
|
if (options == null ? void 0 : options.arguments) Object.assign(args, options.arguments);
|
|
125
|
-
await this.channel.
|
|
126
|
-
exchange,
|
|
127
|
-
type,
|
|
120
|
+
await this.channel.assertExchange(exchange, type, {
|
|
128
121
|
durable: options == null ? void 0 : options.durable,
|
|
129
122
|
internal: options == null ? void 0 : options.internal,
|
|
130
123
|
autoDelete: options == null ? void 0 : options.autoDelete,
|
|
@@ -135,37 +128,26 @@ var RabbitMQClientChannel = class {
|
|
|
135
128
|
};
|
|
136
129
|
}
|
|
137
130
|
async checkExchange(exchange) {
|
|
138
|
-
await this.channel.
|
|
139
|
-
exchange,
|
|
140
|
-
passive: true
|
|
141
|
-
});
|
|
131
|
+
await this.channel.checkExchange(exchange);
|
|
142
132
|
return {
|
|
143
133
|
exchange
|
|
144
134
|
};
|
|
145
135
|
}
|
|
146
136
|
async deleteExchange(exchange, options) {
|
|
147
|
-
await this.channel.
|
|
148
|
-
exchange,
|
|
137
|
+
await this.channel.deleteExchange(exchange, {
|
|
149
138
|
ifUnused: options == null ? void 0 : options.ifUnused
|
|
150
139
|
});
|
|
151
140
|
}
|
|
152
141
|
async bindQueue(queue, source, pattern, args) {
|
|
153
|
-
await this.channel.
|
|
154
|
-
queue,
|
|
155
|
-
exchange: source,
|
|
156
|
-
routingKey: pattern,
|
|
157
|
-
arguments: args
|
|
158
|
-
});
|
|
142
|
+
await this.channel.bindQueue(queue, source, pattern, args);
|
|
159
143
|
}
|
|
160
144
|
publish(exchange, routingKey, content, options) {
|
|
161
145
|
var _a2;
|
|
162
|
-
this.channel.
|
|
163
|
-
exchange,
|
|
164
|
-
routingKey,
|
|
146
|
+
return this.channel.publish(exchange, routingKey, content, {
|
|
165
147
|
correlationId: options == null ? void 0 : options.correlationId,
|
|
166
148
|
messageId: options == null ? void 0 : options.messageId,
|
|
167
149
|
headers: options == null ? void 0 : options.headers,
|
|
168
|
-
|
|
150
|
+
persistent: options == null ? void 0 : options.persistent,
|
|
169
151
|
expiration: (_a2 = options == null ? void 0 : options.expiration) == null ? void 0 : _a2.toString(),
|
|
170
152
|
contentType: options == null ? void 0 : options.contentType,
|
|
171
153
|
contentEncoding: options == null ? void 0 : options.contentEncoding,
|
|
@@ -175,79 +157,106 @@ var RabbitMQClientChannel = class {
|
|
|
175
157
|
type: options == null ? void 0 : options.type,
|
|
176
158
|
userId: options == null ? void 0 : options.userId,
|
|
177
159
|
appId: options == null ? void 0 : options.appId
|
|
178
|
-
}
|
|
179
|
-
return true;
|
|
160
|
+
});
|
|
180
161
|
}
|
|
181
162
|
async consume(queue, onMessage, options) {
|
|
182
|
-
const result = await this.channel.
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
exclusive: options == null ? void 0 : options.exclusive,
|
|
188
|
-
arguments: options == null ? void 0 : options.arguments
|
|
189
|
-
}, (msg) => {
|
|
190
|
-
const body = msg.body;
|
|
191
|
-
const content = Buffer.isBuffer(body) ? body : typeof body === "string" ? Buffer.from(body) : Buffer.from(JSON.stringify(body));
|
|
163
|
+
const result = await this.channel.consume(queue, (msg) => {
|
|
164
|
+
if (msg === null) {
|
|
165
|
+
onMessage(null);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
192
168
|
const consumeMessage = {
|
|
193
|
-
content,
|
|
169
|
+
content: msg.content,
|
|
194
170
|
fields: {
|
|
195
|
-
consumerTag: msg.consumerTag,
|
|
196
|
-
deliveryTag: msg.deliveryTag,
|
|
197
|
-
redelivered: msg.redelivered,
|
|
198
|
-
exchange: msg.exchange,
|
|
199
|
-
routingKey: msg.routingKey
|
|
171
|
+
consumerTag: msg.fields.consumerTag,
|
|
172
|
+
deliveryTag: msg.fields.deliveryTag,
|
|
173
|
+
redelivered: msg.fields.redelivered,
|
|
174
|
+
exchange: msg.fields.exchange,
|
|
175
|
+
routingKey: msg.fields.routingKey
|
|
200
176
|
},
|
|
201
177
|
properties: {
|
|
202
|
-
contentType: msg.contentType,
|
|
203
|
-
contentEncoding: msg.contentEncoding,
|
|
204
|
-
headers: msg.headers || {},
|
|
205
|
-
deliveryMode: msg.
|
|
206
|
-
priority: msg.priority,
|
|
207
|
-
correlationId: msg.correlationId,
|
|
208
|
-
replyTo: msg.replyTo,
|
|
209
|
-
expiration: msg.expiration,
|
|
210
|
-
messageId: msg.messageId,
|
|
211
|
-
timestamp: msg.timestamp,
|
|
212
|
-
type: msg.type,
|
|
213
|
-
userId: msg.userId,
|
|
214
|
-
appId: msg.appId
|
|
178
|
+
contentType: msg.properties.contentType || void 0,
|
|
179
|
+
contentEncoding: msg.properties.contentEncoding || void 0,
|
|
180
|
+
headers: msg.properties.headers || {},
|
|
181
|
+
deliveryMode: msg.properties.deliveryMode,
|
|
182
|
+
priority: msg.properties.priority,
|
|
183
|
+
correlationId: msg.properties.correlationId || void 0,
|
|
184
|
+
replyTo: msg.properties.replyTo || void 0,
|
|
185
|
+
expiration: msg.properties.expiration || void 0,
|
|
186
|
+
messageId: msg.properties.messageId || void 0,
|
|
187
|
+
timestamp: msg.properties.timestamp,
|
|
188
|
+
type: msg.properties.type || void 0,
|
|
189
|
+
userId: msg.properties.userId || void 0,
|
|
190
|
+
appId: msg.properties.appId || void 0
|
|
215
191
|
}
|
|
216
192
|
};
|
|
217
193
|
onMessage(consumeMessage);
|
|
194
|
+
}, {
|
|
195
|
+
consumerTag: options == null ? void 0 : options.consumerTag,
|
|
196
|
+
noLocal: options == null ? void 0 : options.noLocal,
|
|
197
|
+
noAck: options == null ? void 0 : options.noAck,
|
|
198
|
+
exclusive: options == null ? void 0 : options.exclusive,
|
|
199
|
+
priority: options == null ? void 0 : options.priority,
|
|
200
|
+
arguments: options == null ? void 0 : options.arguments
|
|
218
201
|
});
|
|
219
202
|
return {
|
|
220
203
|
consumerTag: result.consumerTag
|
|
221
204
|
};
|
|
222
205
|
}
|
|
223
206
|
ack(message, allUpTo) {
|
|
224
|
-
this.channel.
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
207
|
+
this.channel.ack(
|
|
208
|
+
{ fields: message.fields, content: message.content, properties: message.properties },
|
|
209
|
+
allUpTo
|
|
210
|
+
);
|
|
228
211
|
}
|
|
229
212
|
nack(message, allUpTo, requeue) {
|
|
230
|
-
this.channel.
|
|
231
|
-
|
|
232
|
-
|
|
213
|
+
this.channel.nack(
|
|
214
|
+
{ fields: message.fields, content: message.content, properties: message.properties },
|
|
215
|
+
allUpTo,
|
|
233
216
|
requeue
|
|
234
|
-
|
|
217
|
+
);
|
|
235
218
|
}
|
|
236
219
|
async prefetch(count, global) {
|
|
237
|
-
await this.channel.
|
|
238
|
-
prefetchCount: count,
|
|
239
|
-
global
|
|
240
|
-
});
|
|
220
|
+
await this.channel.prefetch(count, global);
|
|
241
221
|
}
|
|
242
222
|
async close() {
|
|
243
223
|
await this.channel.close();
|
|
244
224
|
}
|
|
245
225
|
};
|
|
246
226
|
|
|
247
|
-
// src/core/
|
|
248
|
-
var
|
|
249
|
-
constructor(
|
|
227
|
+
// src/core/logging/RunMQConsoleLogger.ts
|
|
228
|
+
var RunMQConsoleLogger = class {
|
|
229
|
+
constructor() {
|
|
230
|
+
this.prefix = "[RunMQ] - ";
|
|
231
|
+
}
|
|
232
|
+
log(message) {
|
|
233
|
+
console.log(this.formatMessage(message));
|
|
234
|
+
}
|
|
235
|
+
error(message, ...optionalParams) {
|
|
236
|
+
console.error(this.formatMessage(message), ...optionalParams);
|
|
237
|
+
}
|
|
238
|
+
warn(message, ...optionalParams) {
|
|
239
|
+
console.warn(this.formatMessage(message), ...optionalParams);
|
|
240
|
+
}
|
|
241
|
+
info(message, ...optionalParams) {
|
|
242
|
+
console.info(this.formatMessage(message), ...optionalParams);
|
|
243
|
+
}
|
|
244
|
+
debug(message, ...optionalParams) {
|
|
245
|
+
console.debug(this.formatMessage(message), ...optionalParams);
|
|
246
|
+
}
|
|
247
|
+
verbose(message, ...optionalParams) {
|
|
248
|
+
console.debug(this.formatMessage(message), ...optionalParams);
|
|
249
|
+
}
|
|
250
|
+
formatMessage(message) {
|
|
251
|
+
return `${this.prefix} ${message}`;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
// src/core/clients/AmqplibClientAdapter.ts
|
|
256
|
+
var AmqplibClientAdapter = class {
|
|
257
|
+
constructor(config, logger = new RunMQConsoleLogger()) {
|
|
250
258
|
this.config = config;
|
|
259
|
+
this.logger = logger;
|
|
251
260
|
this.isConnected = false;
|
|
252
261
|
this.acquiredChannels = [];
|
|
253
262
|
}
|
|
@@ -263,38 +272,20 @@ var RabbitMQClientAdapter = class {
|
|
|
263
272
|
}
|
|
264
273
|
this.connection = void 0;
|
|
265
274
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
// Disable automatic retries - we handle retries at RunMQ level
|
|
269
|
-
retryLow: 100,
|
|
270
|
-
retryHigh: 200,
|
|
271
|
-
connectionTimeout: 5e3
|
|
272
|
-
});
|
|
275
|
+
const connection = await import_amqplib.default.connect(this.config.url);
|
|
276
|
+
this.connection = connection;
|
|
273
277
|
this.connection.on("error", (err) => {
|
|
274
|
-
|
|
278
|
+
this.logger.error("RabbitMQ connection error:", { error: err });
|
|
275
279
|
this.isConnected = false;
|
|
276
280
|
});
|
|
277
|
-
this.connection.on("
|
|
278
|
-
this.isConnected =
|
|
279
|
-
});
|
|
280
|
-
this.connection.on("connection.blocked", (reason) => {
|
|
281
|
-
console.warn("RabbitMQ connection blocked:", reason);
|
|
282
|
-
});
|
|
283
|
-
this.connection.on("connection.unblocked", () => {
|
|
284
|
-
console.info("RabbitMQ connection unblocked");
|
|
281
|
+
this.connection.on("close", () => {
|
|
282
|
+
this.isConnected = false;
|
|
285
283
|
});
|
|
286
|
-
await this.connection.onConnect(5e3, true);
|
|
287
284
|
this.isConnected = true;
|
|
288
285
|
return this.connection;
|
|
289
286
|
} catch (error) {
|
|
290
287
|
this.isConnected = false;
|
|
291
|
-
|
|
292
|
-
try {
|
|
293
|
-
this.connection.close();
|
|
294
|
-
} catch (e) {
|
|
295
|
-
}
|
|
296
|
-
this.connection = void 0;
|
|
297
|
-
}
|
|
288
|
+
this.connection = void 0;
|
|
298
289
|
throw new RunMQException(
|
|
299
290
|
Exceptions.CONNECTION_NOT_ESTABLISHED,
|
|
300
291
|
{
|
|
@@ -305,9 +296,9 @@ var RabbitMQClientAdapter = class {
|
|
|
305
296
|
}
|
|
306
297
|
async getChannel() {
|
|
307
298
|
const connection = await this.connect();
|
|
308
|
-
const rawChannel = await connection.
|
|
299
|
+
const rawChannel = await connection.createChannel();
|
|
309
300
|
this.acquiredChannels.push(rawChannel);
|
|
310
|
-
return new
|
|
301
|
+
return new AmqplibChannel(rawChannel);
|
|
311
302
|
}
|
|
312
303
|
async getDefaultChannel() {
|
|
313
304
|
if (!this.defaultChannel) {
|
|
@@ -324,9 +315,7 @@ var RabbitMQClientAdapter = class {
|
|
|
324
315
|
this.acquiredChannels = [];
|
|
325
316
|
for (const channel of channels) {
|
|
326
317
|
try {
|
|
327
|
-
|
|
328
|
-
await channel.close();
|
|
329
|
-
}
|
|
318
|
+
await channel.close();
|
|
330
319
|
} catch (e) {
|
|
331
320
|
}
|
|
332
321
|
}
|
|
@@ -368,7 +357,8 @@ var Constants = {
|
|
|
368
357
|
DEAD_LETTER_ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + "dead_letter_router",
|
|
369
358
|
RETRY_DELAY_QUEUE_PREFIX: RUNMQ_PREFIX + "retry_delay_",
|
|
370
359
|
DLQ_QUEUE_PREFIX: RUNMQ_PREFIX + "dlq_",
|
|
371
|
-
MESSAGE_TTL_OPERATOR_POLICY_PREFIX: RUNMQ_PREFIX + "message_ttl_operator_policy"
|
|
360
|
+
MESSAGE_TTL_OPERATOR_POLICY_PREFIX: RUNMQ_PREFIX + "message_ttl_operator_policy",
|
|
361
|
+
METADATA_STORE_PREFIX: RUNMQ_PREFIX + "metadata_"
|
|
372
362
|
};
|
|
373
363
|
var DEFAULTS = {
|
|
374
364
|
RECONNECT_DELAY: 5e3,
|
|
@@ -446,6 +436,27 @@ var RunMQFailedMessageRejecterProcessor = class {
|
|
|
446
436
|
}
|
|
447
437
|
};
|
|
448
438
|
|
|
439
|
+
// src/core/message/RunMQMessage.ts
|
|
440
|
+
var RunMQMessage = class {
|
|
441
|
+
static isValid(obj) {
|
|
442
|
+
if (typeof obj === "object" && obj !== null) {
|
|
443
|
+
return "message" in obj && "meta" in obj && typeof obj.message === "object" && obj.message !== null && Array.isArray(obj.message) === false && typeof obj.meta === "object" && obj.meta !== null && "id" in obj.meta && "correlationId" in obj.meta && "publishedAt" in obj.meta && typeof obj.meta.id === "string" && typeof obj.meta.correlationId === "string" && typeof obj.meta.publishedAt === "number";
|
|
444
|
+
}
|
|
445
|
+
return false;
|
|
446
|
+
}
|
|
447
|
+
constructor(message, meta) {
|
|
448
|
+
this.message = message;
|
|
449
|
+
this.meta = meta;
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
var RunMQMessageMeta = class {
|
|
453
|
+
constructor(id, publishedAt, correlationId) {
|
|
454
|
+
this.id = id;
|
|
455
|
+
this.correlationId = correlationId;
|
|
456
|
+
this.publishedAt = publishedAt;
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
|
|
449
460
|
// src/core/consumer/ConsumerCreatorUtils.ts
|
|
450
461
|
var ConsumerCreatorUtils = class {
|
|
451
462
|
static getDLQTopicName(topic) {
|
|
@@ -497,7 +508,28 @@ var RunMQRetriesCheckerProcessor = class {
|
|
|
497
508
|
);
|
|
498
509
|
}
|
|
499
510
|
moveToFinalDeadLetter(message) {
|
|
500
|
-
this.
|
|
511
|
+
const originalPayload = this.extractOriginalPayload(message);
|
|
512
|
+
const dlqMessage = new RabbitMQMessage(
|
|
513
|
+
originalPayload,
|
|
514
|
+
message.id,
|
|
515
|
+
message.correlationId,
|
|
516
|
+
message.channel,
|
|
517
|
+
message.amqpMessage,
|
|
518
|
+
message.headers
|
|
519
|
+
);
|
|
520
|
+
this.DLQPublisher.publish(ConsumerCreatorUtils.getDLQTopicName(this.config.name), dlqMessage);
|
|
521
|
+
}
|
|
522
|
+
extractOriginalPayload(message) {
|
|
523
|
+
if (typeof message.message === "string") {
|
|
524
|
+
try {
|
|
525
|
+
const parsed = JSON.parse(message.message);
|
|
526
|
+
if (RunMQMessage.isValid(parsed)) {
|
|
527
|
+
return parsed.message;
|
|
528
|
+
}
|
|
529
|
+
} catch (e) {
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
return message.message;
|
|
501
533
|
}
|
|
502
534
|
acknowledgeMessage(message) {
|
|
503
535
|
try {
|
|
@@ -575,27 +607,6 @@ var RunMQExceptionLoggerProcessor = class {
|
|
|
575
607
|
}
|
|
576
608
|
};
|
|
577
609
|
|
|
578
|
-
// src/core/message/RunMQMessage.ts
|
|
579
|
-
var RunMQMessage = class {
|
|
580
|
-
static isValid(obj) {
|
|
581
|
-
if (typeof obj === "object" && obj !== null) {
|
|
582
|
-
return "message" in obj && "meta" in obj && typeof obj.message === "object" && obj.message !== null && Array.isArray(obj.message) === false && typeof obj.meta === "object" && obj.meta !== null && "id" in obj.meta && "correlationId" in obj.meta && "publishedAt" in obj.meta && typeof obj.meta.id === "string" && typeof obj.meta.correlationId === "string" && typeof obj.meta.publishedAt === "number";
|
|
583
|
-
}
|
|
584
|
-
return false;
|
|
585
|
-
}
|
|
586
|
-
constructor(message, meta) {
|
|
587
|
-
this.message = message;
|
|
588
|
-
this.meta = meta;
|
|
589
|
-
}
|
|
590
|
-
};
|
|
591
|
-
var RunMQMessageMeta = class {
|
|
592
|
-
constructor(id, publishedAt, correlationId) {
|
|
593
|
-
this.id = id;
|
|
594
|
-
this.correlationId = correlationId;
|
|
595
|
-
this.publishedAt = publishedAt;
|
|
596
|
-
}
|
|
597
|
-
};
|
|
598
|
-
|
|
599
610
|
// src/core/serializers/deserializer/validation/AjvSchemaValidator.ts
|
|
600
611
|
var import_ajv = __toESM(require("ajv"), 1);
|
|
601
612
|
var AjvSchemaValidator = class {
|
|
@@ -870,6 +881,91 @@ var RabbitMQManagementClient = class {
|
|
|
870
881
|
return false;
|
|
871
882
|
}
|
|
872
883
|
}
|
|
884
|
+
/**
|
|
885
|
+
* Creates or updates a RabbitMQ parameter.
|
|
886
|
+
* Parameters are custom key-value stores that can hold any JSON data.
|
|
887
|
+
*
|
|
888
|
+
* @param name - The parameter name
|
|
889
|
+
* @param value - The parameter value (any JSON-serializable object)
|
|
890
|
+
*/
|
|
891
|
+
async setParameter(name, value) {
|
|
892
|
+
try {
|
|
893
|
+
const url = `${this.config.url}/api/global-parameters/${encodeURIComponent(name)}`;
|
|
894
|
+
const response = await fetch(url, {
|
|
895
|
+
method: "PUT",
|
|
896
|
+
headers: {
|
|
897
|
+
"Content-Type": "application/json",
|
|
898
|
+
"Authorization": this.getAuthHeader()
|
|
899
|
+
},
|
|
900
|
+
body: JSON.stringify({ value })
|
|
901
|
+
});
|
|
902
|
+
if (!response.ok) {
|
|
903
|
+
const error = await response.text();
|
|
904
|
+
this.logger.error(`Failed to set parameter ${name}: ${response.status} - ${error}`);
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
this.logger.info(`Successfully set parameter: ${name}`);
|
|
908
|
+
return true;
|
|
909
|
+
} catch (error) {
|
|
910
|
+
this.logger.error(`Error setting parameter: ${error}`);
|
|
911
|
+
return false;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Gets a RabbitMQ parameter.
|
|
916
|
+
*
|
|
917
|
+
* @param name - The parameter name
|
|
918
|
+
*/
|
|
919
|
+
async getParameter(name) {
|
|
920
|
+
try {
|
|
921
|
+
const url = `${this.config.url}/api/global-parameters/${encodeURIComponent(name)}`;
|
|
922
|
+
const response = await fetch(url, {
|
|
923
|
+
method: "GET",
|
|
924
|
+
headers: {
|
|
925
|
+
"Authorization": this.getAuthHeader()
|
|
926
|
+
}
|
|
927
|
+
});
|
|
928
|
+
if (!response.ok) {
|
|
929
|
+
if (response.status === 404) {
|
|
930
|
+
return null;
|
|
931
|
+
}
|
|
932
|
+
const error = await response.text();
|
|
933
|
+
this.logger.error(`Failed to get parameter ${name}: ${response.status} - ${error}`);
|
|
934
|
+
return null;
|
|
935
|
+
}
|
|
936
|
+
const data = await response.json();
|
|
937
|
+
return data.value;
|
|
938
|
+
} catch (error) {
|
|
939
|
+
this.logger.error(`Error getting parameter: ${error}`);
|
|
940
|
+
return null;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Deletes a RabbitMQ parameter.
|
|
945
|
+
*
|
|
946
|
+
* @param name - The parameter name
|
|
947
|
+
*/
|
|
948
|
+
async deleteParameter(name) {
|
|
949
|
+
try {
|
|
950
|
+
const url = `${this.config.url}/api/global-parameters/${encodeURIComponent(name)}`;
|
|
951
|
+
const response = await fetch(url, {
|
|
952
|
+
method: "DELETE",
|
|
953
|
+
headers: {
|
|
954
|
+
"Authorization": this.getAuthHeader()
|
|
955
|
+
}
|
|
956
|
+
});
|
|
957
|
+
if (!response.ok && response.status !== 404) {
|
|
958
|
+
const error = await response.text();
|
|
959
|
+
this.logger.error(`Failed to delete parameter ${name}: ${response.status} - ${error}`);
|
|
960
|
+
return false;
|
|
961
|
+
}
|
|
962
|
+
this.logger.info(`Successfully deleted parameter: ${name}`);
|
|
963
|
+
return true;
|
|
964
|
+
} catch (error) {
|
|
965
|
+
this.logger.error(`Error deleting parameter: ${error}`);
|
|
966
|
+
return false;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
873
969
|
};
|
|
874
970
|
|
|
875
971
|
// src/core/management/Policies/RabbitMQMessageTTLPolicy.ts
|
|
@@ -899,6 +995,9 @@ var RunMQTTLPolicyManager = class {
|
|
|
899
995
|
}
|
|
900
996
|
}
|
|
901
997
|
async initialize() {
|
|
998
|
+
if (this.isManagementPluginEnabled) {
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
902
1001
|
if (!this.managementClient) {
|
|
903
1002
|
this.logger.warn("Management client not configured");
|
|
904
1003
|
return;
|
|
@@ -931,21 +1030,166 @@ var RunMQTTLPolicyManager = class {
|
|
|
931
1030
|
}
|
|
932
1031
|
};
|
|
933
1032
|
|
|
1033
|
+
// src/core/management/Policies/RunMQQueueMetadata.ts
|
|
1034
|
+
var METADATA_SCHEMA_VERSION = 0;
|
|
1035
|
+
|
|
1036
|
+
// src/core/management/Policies/RabbitMQMetadata.ts
|
|
1037
|
+
var RabbitMQMetadata = class {
|
|
1038
|
+
/**
|
|
1039
|
+
* Creates metadata for a queue.
|
|
1040
|
+
* @param maxRetries - Maximum retry attempts configured for the queue
|
|
1041
|
+
* @param existingMetadata - Optional existing metadata to preserve createdAt
|
|
1042
|
+
* @returns RunMQQueueMetadata object
|
|
1043
|
+
*/
|
|
1044
|
+
static createMetadataFor(maxRetries, existingMetadata) {
|
|
1045
|
+
var _a2;
|
|
1046
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1047
|
+
return __spreadValues({
|
|
1048
|
+
version: METADATA_SCHEMA_VERSION,
|
|
1049
|
+
maxRetries,
|
|
1050
|
+
createdAt: (_a2 = existingMetadata == null ? void 0 : existingMetadata.createdAt) != null ? _a2 : now
|
|
1051
|
+
}, existingMetadata ? { updatedAt: now } : {});
|
|
1052
|
+
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Gets the parameter name for a given queue.
|
|
1055
|
+
*/
|
|
1056
|
+
static getParameterName(queueName) {
|
|
1057
|
+
return Constants.METADATA_STORE_PREFIX + queueName;
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
// src/core/management/Policies/RunMQMetadataManager.ts
|
|
1062
|
+
var RunMQMetadataManager = class {
|
|
1063
|
+
constructor(logger, managementConfig) {
|
|
1064
|
+
this.logger = logger;
|
|
1065
|
+
this.managementConfig = managementConfig;
|
|
1066
|
+
this.managementClient = null;
|
|
1067
|
+
this.isManagementPluginEnabled = false;
|
|
1068
|
+
if (this.managementConfig) {
|
|
1069
|
+
this.managementClient = new RabbitMQManagementClient(this.managementConfig, this.logger);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Initialize the manager by checking if management plugin is available.
|
|
1074
|
+
*/
|
|
1075
|
+
async initialize() {
|
|
1076
|
+
if (this.isManagementPluginEnabled) {
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
if (!this.managementClient) {
|
|
1080
|
+
this.logger.warn("Management client not configured - metadata storage disabled");
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
this.isManagementPluginEnabled = await this.managementClient.checkManagementPluginEnabled();
|
|
1084
|
+
if (!this.isManagementPluginEnabled) {
|
|
1085
|
+
this.logger.warn("RabbitMQ management plugin is not enabled - metadata storage disabled");
|
|
1086
|
+
} else {
|
|
1087
|
+
this.logger.info("RunMQ metadata storage initialized");
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
/**
|
|
1091
|
+
* Store or update metadata for a queue.
|
|
1092
|
+
* If metadata already exists, preserves createdAt and sets updatedAt.
|
|
1093
|
+
*
|
|
1094
|
+
* @param queueName - The name of the queue
|
|
1095
|
+
* @param maxRetries - Maximum retry attempts
|
|
1096
|
+
* @returns true if metadata was stored successfully, false otherwise
|
|
1097
|
+
*/
|
|
1098
|
+
async apply(queueName, maxRetries) {
|
|
1099
|
+
if (!this.isManagementPluginEnabled || !this.managementClient) {
|
|
1100
|
+
this.logger.warn(`Cannot store metadata for queue '${queueName}' - management plugin not available`);
|
|
1101
|
+
return false;
|
|
1102
|
+
}
|
|
1103
|
+
try {
|
|
1104
|
+
const existingMetadata = await this.getMetadata(queueName);
|
|
1105
|
+
const metadata = RabbitMQMetadata.createMetadataFor(
|
|
1106
|
+
maxRetries,
|
|
1107
|
+
existingMetadata != null ? existingMetadata : void 0
|
|
1108
|
+
);
|
|
1109
|
+
const paramName = RabbitMQMetadata.getParameterName(queueName);
|
|
1110
|
+
const success = await this.managementClient.setParameter(
|
|
1111
|
+
paramName,
|
|
1112
|
+
metadata
|
|
1113
|
+
);
|
|
1114
|
+
if (success) {
|
|
1115
|
+
const action = existingMetadata ? "Updated" : "Created";
|
|
1116
|
+
this.logger.info(`${action} metadata for queue: ${queueName}`);
|
|
1117
|
+
return true;
|
|
1118
|
+
}
|
|
1119
|
+
this.logger.error(`Failed to store metadata for queue: ${queueName}`);
|
|
1120
|
+
return false;
|
|
1121
|
+
} catch (error) {
|
|
1122
|
+
this.logger.error(`Error storing metadata for queue ${queueName}: ${error}`);
|
|
1123
|
+
return false;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Get metadata for a queue.
|
|
1128
|
+
*
|
|
1129
|
+
* @param queueName - The name of the queue
|
|
1130
|
+
* @returns The queue metadata or null if not found
|
|
1131
|
+
*/
|
|
1132
|
+
async getMetadata(queueName) {
|
|
1133
|
+
if (!this.isManagementPluginEnabled || !this.managementClient) {
|
|
1134
|
+
return null;
|
|
1135
|
+
}
|
|
1136
|
+
try {
|
|
1137
|
+
const paramName = RabbitMQMetadata.getParameterName(queueName);
|
|
1138
|
+
return await this.managementClient.getParameter(
|
|
1139
|
+
paramName
|
|
1140
|
+
);
|
|
1141
|
+
} catch (error) {
|
|
1142
|
+
this.logger.warn(`Failed to get metadata for queue ${queueName}: ${error}`);
|
|
1143
|
+
return null;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Delete metadata for a queue.
|
|
1148
|
+
*
|
|
1149
|
+
* @param queueName - The name of the queue
|
|
1150
|
+
*/
|
|
1151
|
+
async cleanup(queueName) {
|
|
1152
|
+
if (!this.isManagementPluginEnabled || !this.managementClient) {
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
const paramName = RabbitMQMetadata.getParameterName(queueName);
|
|
1156
|
+
await this.managementClient.deleteParameter(paramName);
|
|
1157
|
+
this.logger.info(`Deleted metadata for queue: ${queueName}`);
|
|
1158
|
+
}
|
|
1159
|
+
/**
|
|
1160
|
+
* Check if management plugin is enabled and metadata storage is available.
|
|
1161
|
+
*/
|
|
1162
|
+
isEnabled() {
|
|
1163
|
+
return this.isManagementPluginEnabled;
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
|
|
934
1167
|
// src/core/consumer/RunMQConsumerCreator.ts
|
|
935
1168
|
var RunMQConsumerCreator = class {
|
|
936
1169
|
constructor(client, logger, managementConfig) {
|
|
937
1170
|
this.client = client;
|
|
938
1171
|
this.logger = logger;
|
|
939
1172
|
this.ttlPolicyManager = new RunMQTTLPolicyManager(logger, managementConfig);
|
|
1173
|
+
this.metadataManager = new RunMQMetadataManager(logger, managementConfig);
|
|
940
1174
|
}
|
|
941
1175
|
async createConsumer(consumerConfiguration) {
|
|
942
1176
|
await this.ttlPolicyManager.initialize();
|
|
1177
|
+
await this.metadataManager.initialize();
|
|
943
1178
|
await this.assertQueues(consumerConfiguration);
|
|
944
1179
|
await this.bindQueues(consumerConfiguration);
|
|
1180
|
+
await this.storeMetadata(consumerConfiguration);
|
|
945
1181
|
for (let i = 0; i < consumerConfiguration.processorConfig.consumersCount; i++) {
|
|
946
1182
|
await this.runProcessor(consumerConfiguration);
|
|
947
1183
|
}
|
|
948
1184
|
}
|
|
1185
|
+
async storeMetadata(consumerConfiguration) {
|
|
1186
|
+
var _a2;
|
|
1187
|
+
const maxRetries = (_a2 = consumerConfiguration.processorConfig.attempts) != null ? _a2 : DEFAULTS.PROCESSING_ATTEMPTS;
|
|
1188
|
+
await this.metadataManager.apply(
|
|
1189
|
+
consumerConfiguration.processorConfig.name,
|
|
1190
|
+
maxRetries
|
|
1191
|
+
);
|
|
1192
|
+
}
|
|
949
1193
|
async runProcessor(consumerConfiguration) {
|
|
950
1194
|
const consumerChannel = await this.getProcessorChannel();
|
|
951
1195
|
const DLQPublisher = new RunMQPublisherCreator(this.logger).createPublisher(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME);
|
|
@@ -1062,34 +1306,6 @@ var ConsumerConfiguration = class {
|
|
|
1062
1306
|
}
|
|
1063
1307
|
};
|
|
1064
1308
|
|
|
1065
|
-
// src/core/logging/RunMQConsoleLogger.ts
|
|
1066
|
-
var RunMQConsoleLogger = class {
|
|
1067
|
-
constructor() {
|
|
1068
|
-
this.prefix = "[RunMQ] - ";
|
|
1069
|
-
}
|
|
1070
|
-
log(message) {
|
|
1071
|
-
console.log(this.formatMessage(message));
|
|
1072
|
-
}
|
|
1073
|
-
error(message, ...optionalParams) {
|
|
1074
|
-
console.error(this.formatMessage(message), ...optionalParams);
|
|
1075
|
-
}
|
|
1076
|
-
warn(message, ...optionalParams) {
|
|
1077
|
-
console.warn(this.formatMessage(message), ...optionalParams);
|
|
1078
|
-
}
|
|
1079
|
-
info(message, ...optionalParams) {
|
|
1080
|
-
console.info(this.formatMessage(message), ...optionalParams);
|
|
1081
|
-
}
|
|
1082
|
-
debug(message, ...optionalParams) {
|
|
1083
|
-
console.debug(this.formatMessage(message), ...optionalParams);
|
|
1084
|
-
}
|
|
1085
|
-
verbose(message, ...optionalParams) {
|
|
1086
|
-
console.debug(this.formatMessage(message), ...optionalParams);
|
|
1087
|
-
}
|
|
1088
|
-
formatMessage(message) {
|
|
1089
|
-
return `${this.prefix} ${message}`;
|
|
1090
|
-
}
|
|
1091
|
-
};
|
|
1092
|
-
|
|
1093
1309
|
// src/core/message/RabbitMQMessageProperties.ts
|
|
1094
1310
|
var RabbitMQMessageProperties = class {
|
|
1095
1311
|
constructor(id, correlationId) {
|
|
@@ -1108,7 +1324,8 @@ var RunMQ = class _RunMQ {
|
|
|
1108
1324
|
reconnectDelay: (_a2 = config.reconnectDelay) != null ? _a2 : DEFAULTS.RECONNECT_DELAY,
|
|
1109
1325
|
maxReconnectAttempts: (_b = config.maxReconnectAttempts) != null ? _b : DEFAULTS.MAX_RECONNECT_ATTEMPTS
|
|
1110
1326
|
});
|
|
1111
|
-
this.client = new
|
|
1327
|
+
this.client = new AmqplibClientAdapter(this.config, this.logger);
|
|
1328
|
+
this.consumer = new RunMQConsumerCreator(this.client, this.logger, this.config.management);
|
|
1112
1329
|
}
|
|
1113
1330
|
/**
|
|
1114
1331
|
* Starts the RunMQ instance by establishing a connection to RabbitMQ and initializing necessary components.
|
|
@@ -1129,8 +1346,7 @@ var RunMQ = class _RunMQ {
|
|
|
1129
1346
|
* @param processor The function that will process the incoming messages
|
|
1130
1347
|
*/
|
|
1131
1348
|
async process(topic, config, processor) {
|
|
1132
|
-
|
|
1133
|
-
await consumer.createConsumer(new ConsumerConfiguration(topic, config, processor));
|
|
1349
|
+
await this.consumer.createConsumer(new ConsumerConfiguration(topic, config, processor));
|
|
1134
1350
|
}
|
|
1135
1351
|
/**
|
|
1136
1352
|
* Publishes a message to the specified topic with an optional correlation ID
|
|
@@ -1189,7 +1405,6 @@ var RunMQ = class _RunMQ {
|
|
|
1189
1405
|
return;
|
|
1190
1406
|
} catch (error) {
|
|
1191
1407
|
this.retryAttempts++;
|
|
1192
|
-
console.log(this.logger);
|
|
1193
1408
|
this.logger.error(`Connection attempt ${this.retryAttempts}/${maxAttempts} failed:`, error);
|
|
1194
1409
|
if (this.retryAttempts >= maxAttempts) {
|
|
1195
1410
|
throw new RunMQException(
|