@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
@@ -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 : '/etc/rabbitmq/rabbitMQConfig.json',
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<true | undefined>;
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 | undefined>;
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
- // Publish the message
203
- // Logger.debug('Reached:publishMessageToExchange', 'publishMessageToExchange',{classInstance, messagePublisherErrorHandler});
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
- if (isConnectionOpen) {
206
- // let attempt: number = 0;
207
- const exchangeName = (_a = request === null || request === void 0 ? void 0 : request.exchangeName) !== null && _a !== void 0 ? _a : '';
208
- const queueName = request.queueName;
209
- const data = request === null || request === void 0 ? void 0 : request.message;
210
- // const options:object | null = request?.options; // Optional parameter for retry count if you wnats to override the default retry count
211
- const messageBuffer = Buffer.from(JSON.stringify(data.message));
212
- // let retries: number = typeof data.message === 'object' && data.message !== null ? (data.message as { retries: number }).retries ?? 0 : 0;
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 (sent) {
220
- logger_1.Logger.debug(`Message sent successfully`, 'publishMessageToExchange', { data, queueName });
221
- resolve(true);
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
- logger_1.Logger.error(`Failed to publish message to exchange.`, 'publishMessageToExchange', { message: messageBuffer.toString() });
225
- reject(false);
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(`Error sending message: ${error}`, 'sendMessage');
254
- throw new Error("Failed to publish message to exchange");
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 later queue", 'sendMessageToDeadLater');
435
+ logger_1.Logger.info("Reached: send message on dead letter queue", 'sendMessageToDeadLater');
444
436
  try {
445
437
  if (isConnectionOpen) {
446
- return channel.sendToQueue(dlx_queue, Buffer.from(JSON.stringify(data)), {
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("Error in send message on dead later queue", 'sendMessageToDeadLater', { message: error.message });
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.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
+ }