@platform-x/hep-message-broker-client 1.0.0 → 1.0.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
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
# hep-message-broker-client
|
|
1
|
+
# hep-message-broker-client
|
package/dist/src/config/index.js
CHANGED
|
@@ -32,7 +32,7 @@ exports.default = {
|
|
|
32
32
|
CONNECTION_ERROR: (_q = process.env.RABBITMQ_CONNECTION_ERROR) !== null && _q !== void 0 ? _q : false,
|
|
33
33
|
PUBLISHER_ERROR: (_r = process.env.RABBITMQ_PUBLISHER_ERROR) !== null && _r !== void 0 ? _r : false,
|
|
34
34
|
CONSUMER_ERROR: (_s = process.env.RABBITMQ_CONSUMER_ERROR) !== null && _s !== void 0 ? _s : false,
|
|
35
|
-
CONFIG_PATH: (_t = process.env.CONFIG_PATH) !== null && _t !== void 0 ? _t :
|
|
35
|
+
CONFIG_PATH: (_t = process.env.CONFIG_PATH) !== null && _t !== void 0 ? _t : "C:/platform-X/rabbitMQConfig.json",
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
38
|
//# sourceMappingURL=index.js.map
|
|
@@ -32,7 +32,7 @@ export declare class MessageBrokerClient {
|
|
|
32
32
|
* @param messagePublisherErrorHandler
|
|
33
33
|
* @returns
|
|
34
34
|
*/
|
|
35
|
-
publishMessageToExchange(request: PublishMessageInputType): Promise<
|
|
35
|
+
publishMessageToExchange(request: PublishMessageInputType): Promise<boolean>;
|
|
36
36
|
/**
|
|
37
37
|
* Funciton to message handler
|
|
38
38
|
*/
|
|
@@ -62,7 +62,7 @@ export declare class MessageBrokerClient {
|
|
|
62
62
|
* @param queueName
|
|
63
63
|
* @retruns
|
|
64
64
|
*/
|
|
65
|
-
sendMessageToDeadLatter(attempt: number, data: any): Promise<boolean
|
|
65
|
+
sendMessageToDeadLatter(attempt: number, data: any): Promise<boolean>;
|
|
66
66
|
/***
|
|
67
67
|
* Function to send message to retry queue
|
|
68
68
|
* @param attempt
|
|
@@ -79,6 +79,14 @@ export declare class MessageBrokerClient {
|
|
|
79
79
|
* @returns
|
|
80
80
|
*/
|
|
81
81
|
findQueueAndExchange(queueName: string, exchangeName: string): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Function to check connection and channel
|
|
84
|
+
*/
|
|
85
|
+
private checkConnectionAndChannel;
|
|
86
|
+
/**
|
|
87
|
+
* Function to recreate channel
|
|
88
|
+
*/
|
|
89
|
+
private recreateChannel;
|
|
82
90
|
/**
|
|
83
91
|
* Function to setup the queues and exchanges
|
|
84
92
|
* @params array
|
|
@@ -199,63 +199,55 @@ class MessageBrokerClient {
|
|
|
199
199
|
return __awaiter(this, void 0, void 0, function* () {
|
|
200
200
|
var _a;
|
|
201
201
|
logger_1.Logger.info('Reached:publishMessageToExchange', 'publishMessageToExchange');
|
|
202
|
-
|
|
203
|
-
|
|
202
|
+
let attempt = 0;
|
|
203
|
+
const exchangeName = (_a = request === null || request === void 0 ? void 0 : request.exchangeName) !== null && _a !== void 0 ? _a : '';
|
|
204
|
+
const queueName = request.queueName;
|
|
205
|
+
const data = request === null || request === void 0 ? void 0 : request.message;
|
|
206
|
+
const messageBuffer = Buffer.from(JSON.stringify(data.message));
|
|
204
207
|
try {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
// while (attempt < maxRetries) {
|
|
214
|
-
const isSent = yield new Promise((resolve, reject) => {
|
|
215
|
-
const sent = channel.publish(exchangeName, queueName, messageBuffer, {
|
|
216
|
-
persistent: true, // Ensures the message is persisted
|
|
217
|
-
// correlationId: this.correlationId,
|
|
208
|
+
// 1. Ensure connection and channel exists
|
|
209
|
+
yield this.checkConnectionAndChannel();
|
|
210
|
+
// 2. Retry loop
|
|
211
|
+
while (attempt < maxRetries) {
|
|
212
|
+
try {
|
|
213
|
+
logger_1.Logger.info(`Attempting to publish message`, 'publishMessageToExchange');
|
|
214
|
+
let sent = channel.publish(exchangeName, queueName, messageBuffer, {
|
|
215
|
+
persistent: true,
|
|
218
216
|
});
|
|
219
|
-
if
|
|
220
|
-
|
|
221
|
-
|
|
217
|
+
// if(attempt <1){ sent = false}else{sent = true} // Simulate failure for testing retry logic
|
|
218
|
+
if (sent && (RABBITMQ.PUBLISHER_ERROR !== 'true' && RABBITMQ.PUBLISHER_ERROR !== true)) {
|
|
219
|
+
logger_1.Logger.info(`Message published successfully on attempt ${attempt + 1}`, 'publishMessageToExchange');
|
|
220
|
+
logger_1.Logger.info(`✅ Message sent successfully`, 'publishMessageToExchange');
|
|
221
|
+
break;
|
|
222
222
|
}
|
|
223
223
|
else {
|
|
224
|
-
|
|
225
|
-
|
|
224
|
+
throw new Error('Publish returned false');
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
attempt++;
|
|
229
|
+
logger_1.Logger.error(`Failed attempt ${attempt} to publish message`, 'publishMessageToExchange', error);
|
|
230
|
+
if (attempt < maxRetries) {
|
|
231
|
+
logger_1.Logger.info(`Retrying in ${retry_delay}ms...`, 'publishMessageToExchange');
|
|
232
|
+
yield new Promise(res => setTimeout(res, retry_delay));
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
logger_1.Logger.error(`Error in publishMessageToExchange: ${error}`, 'publishMessageToExchange');
|
|
236
|
+
throw new Error('Max retries reached');
|
|
226
237
|
}
|
|
227
|
-
});
|
|
228
|
-
if ((isSent) && (RABBITMQ.PUBLISHER_ERROR !== 'true' && RABBITMQ.PUBLISHER_ERROR !== true)) {
|
|
229
|
-
return isSent;
|
|
230
238
|
}
|
|
231
|
-
// else{
|
|
232
|
-
// let queueName = (request as PublishMessageInputType)?.queueName
|
|
233
|
-
// if (attempt >= maxRetries) {
|
|
234
|
-
// Logger.error('Max retries reached. Failed to publish message.', 'publishMessageToExchange', request);
|
|
235
|
-
// // Optionally: Log or persist the failed message to a DB, file, or other storage for manual intervention
|
|
236
|
-
// this.sendMessageToDeadLatter(attempt, data, queueName);
|
|
237
|
-
// this.messagePublisherErrorHandler(request); // we need to comment this line
|
|
238
|
-
// if (typeof classInstance[messagePublisherErrorHandler] === 'function') {
|
|
239
|
-
// classInstance[messagePublisherErrorHandler](data); // Dynamically call the method
|
|
240
|
-
// } else {
|
|
241
|
-
// Logger.info(`Method ${messagePublisherErrorHandler} not found in classInstance.`, 'publishMessageToExchange');
|
|
242
|
-
// }
|
|
243
|
-
// return false;
|
|
244
|
-
// }else{
|
|
245
|
-
// await this.publishMessageRetryQueue(request, (attempt+1));
|
|
246
|
-
// attempt++;
|
|
247
|
-
// }
|
|
248
|
-
// }
|
|
249
|
-
// }
|
|
250
239
|
}
|
|
240
|
+
return true;
|
|
251
241
|
}
|
|
252
242
|
catch (error) {
|
|
253
|
-
logger_1.Logger.error(
|
|
254
|
-
|
|
243
|
+
logger_1.Logger.error('Max retries reached. Sending message to Dead Letter Queue...', 'publishMessageToExchange');
|
|
244
|
+
yield this.sendMessageToDeadLatter(attempt, data);
|
|
245
|
+
const customError = new Error('Failed to publish message to exchange');
|
|
246
|
+
customError.originalError = error; // optional
|
|
247
|
+
throw customError;
|
|
255
248
|
}
|
|
256
249
|
});
|
|
257
250
|
}
|
|
258
|
-
;
|
|
259
251
|
/**
|
|
260
252
|
* Funciton to message handler
|
|
261
253
|
*/
|
|
@@ -440,19 +432,31 @@ class MessageBrokerClient {
|
|
|
440
432
|
*/
|
|
441
433
|
sendMessageToDeadLatter(attempt, data) {
|
|
442
434
|
return __awaiter(this, void 0, void 0, function* () {
|
|
443
|
-
logger_1.Logger.info("Reached: send message on dead
|
|
435
|
+
logger_1.Logger.info("Reached: send message on dead letter queue", 'sendMessageToDeadLater');
|
|
444
436
|
try {
|
|
445
437
|
if (isConnectionOpen) {
|
|
446
|
-
|
|
438
|
+
logger_1.Logger.info(`Attempting to send message to DLX queue: ${dlx_queue} (attempt: ${attempt}, retry-count: ${attempt - 1}, size: ${JSON.stringify(data).length} bytes)`, 'sendMessageToDeadLater');
|
|
439
|
+
const sent = channel.sendToQueue(dlx_queue, Buffer.from(JSON.stringify(data)), {
|
|
447
440
|
persistent: true,
|
|
448
441
|
headers: {
|
|
449
442
|
'x-retry-count': attempt - 1
|
|
450
443
|
},
|
|
451
444
|
});
|
|
445
|
+
if (sent) {
|
|
446
|
+
logger_1.Logger.info(`Message successfully published to DLX queue: ${dlx_queue} (attempt: ${attempt}, retry-count: ${attempt - 1})`, 'sendMessageToDeadLater');
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
logger_1.Logger.error(`Failed to publish message to DLX queue: ${dlx_queue} - Channel buffer full (attempt: ${attempt}, retry-count: ${attempt - 1})`, 'sendMessageToDeadLater');
|
|
450
|
+
}
|
|
451
|
+
return sent;
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
logger_1.Logger.error(`Cannot send message to DLX - Connection is not open (queue: ${dlx_queue}, attempt: ${attempt})`, 'sendMessageToDeadLater');
|
|
455
|
+
return false;
|
|
452
456
|
}
|
|
453
457
|
}
|
|
454
458
|
catch (error) {
|
|
455
|
-
logger_1.Logger.error(
|
|
459
|
+
logger_1.Logger.error(`Error sending message to dead letter queue: ${error.message} (queue: ${dlx_queue}, attempt: ${attempt})`, 'sendMessageToDeadLater');
|
|
456
460
|
throw error;
|
|
457
461
|
}
|
|
458
462
|
});
|
|
@@ -540,6 +544,40 @@ class MessageBrokerClient {
|
|
|
540
544
|
}
|
|
541
545
|
});
|
|
542
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* Function to check connection and channel
|
|
549
|
+
*/
|
|
550
|
+
checkConnectionAndChannel() {
|
|
551
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
552
|
+
logger_1.Logger.info('Reached: checkConnectionAndChannel', 'checkConnectionAndChannel');
|
|
553
|
+
// 🧪 1. Ensure connection exists
|
|
554
|
+
if (!isConnectionOpen) {
|
|
555
|
+
logger_1.Logger.warn('No connection found. Creating new connection...', 'publishMessageToExchange');
|
|
556
|
+
yield this.createConnection();
|
|
557
|
+
}
|
|
558
|
+
// 🧪 2. Ensure channel is alive
|
|
559
|
+
const channelConnection = channel === null || channel === void 0 ? void 0 : channel.connection;
|
|
560
|
+
if (!channel || !channelConnection || channelConnection.stream.destroyed) {
|
|
561
|
+
logger_1.Logger.warn('Channel seems dead, recreating before publish...', 'publishMessageToExchange');
|
|
562
|
+
yield this.recreateChannel();
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Function to recreate channel
|
|
568
|
+
*/
|
|
569
|
+
recreateChannel() {
|
|
570
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
571
|
+
try {
|
|
572
|
+
channel = yield connection.createConfirmChannel();
|
|
573
|
+
channel.prefetch(RABBITMQ === null || RABBITMQ === void 0 ? void 0 : RABBITMQ.PREFETCH_COUNT);
|
|
574
|
+
logger_1.Logger.info(' Channel recreated successfully.', 'recreateChannel');
|
|
575
|
+
}
|
|
576
|
+
catch (err) {
|
|
577
|
+
logger_1.Logger.error(' Failed to recreate channel:', err);
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
}
|
|
543
581
|
/**
|
|
544
582
|
* Function to setup the queues and exchanges
|
|
545
583
|
* @params array
|
package/package.json
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@platform-x/hep-message-broker-client",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "@platform-x/hep-message-broker-client",
|
|
5
|
-
"main": "./dist/src/index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"build": "rimraf dist && tsc"
|
|
8
|
-
},
|
|
9
|
-
"author": "",
|
|
10
|
-
"license": "ISC",
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"@types/amqplib": "^0.10.6",
|
|
13
|
-
"@types/bunyan": "^1.8.11",
|
|
14
|
-
"@types/bunyan-format": "^0.2.9",
|
|
15
|
-
"@types/cls-hooked": "^4.3.9",
|
|
16
|
-
"@types/express": "^5.0.0",
|
|
17
|
-
"@types/lodash": "^4.17.14",
|
|
18
|
-
"amqplib": "^0.10.5",
|
|
19
|
-
"bunyan": "^1.8.15",
|
|
20
|
-
"bunyan-format": "^0.2.1",
|
|
21
|
-
"cls-hooked": "^4.2.2",
|
|
22
|
-
"dotenv": "^16.4.7",
|
|
23
|
-
"express": "^4.21.2",
|
|
24
|
-
"jest": "^29.7.0",
|
|
25
|
-
"lodash": "^4.17.21",
|
|
26
|
-
"tsc-watch": "^6.2.1",
|
|
27
|
-
"typescript": "^5.7.3",
|
|
28
|
-
"uuid": "^11.0.5"
|
|
29
|
-
},
|
|
30
|
-
"devDependencies": {
|
|
31
|
-
"@types/jest": "^29.5.14",
|
|
32
|
-
"@types/node": "^22.10.10",
|
|
33
|
-
"reflect-metadata": "^0.2.2",
|
|
34
|
-
"rimraf": "^6.0.1"
|
|
35
|
-
},
|
|
36
|
-
"private": false,
|
|
37
|
-
"publishConfig": {
|
|
38
|
-
"access": "public"
|
|
39
|
-
}
|
|
40
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@platform-x/hep-message-broker-client",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "@platform-x/hep-message-broker-client",
|
|
5
|
+
"main": "./dist/src/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "rimraf dist && tsc"
|
|
8
|
+
},
|
|
9
|
+
"author": "",
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@types/amqplib": "^0.10.6",
|
|
13
|
+
"@types/bunyan": "^1.8.11",
|
|
14
|
+
"@types/bunyan-format": "^0.2.9",
|
|
15
|
+
"@types/cls-hooked": "^4.3.9",
|
|
16
|
+
"@types/express": "^5.0.0",
|
|
17
|
+
"@types/lodash": "^4.17.14",
|
|
18
|
+
"amqplib": "^0.10.5",
|
|
19
|
+
"bunyan": "^1.8.15",
|
|
20
|
+
"bunyan-format": "^0.2.1",
|
|
21
|
+
"cls-hooked": "^4.2.2",
|
|
22
|
+
"dotenv": "^16.4.7",
|
|
23
|
+
"express": "^4.21.2",
|
|
24
|
+
"jest": "^29.7.0",
|
|
25
|
+
"lodash": "^4.17.21",
|
|
26
|
+
"tsc-watch": "^6.2.1",
|
|
27
|
+
"typescript": "^5.7.3",
|
|
28
|
+
"uuid": "^11.0.5"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/jest": "^29.5.14",
|
|
32
|
+
"@types/node": "^22.10.10",
|
|
33
|
+
"reflect-metadata": "^0.2.2",
|
|
34
|
+
"rimraf": "^6.0.1"
|
|
35
|
+
},
|
|
36
|
+
"private": false,
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
}
|
|
40
|
+
}
|