@itentialopensource/adapter-kafkav2 0.26.4 → 0.26.6

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/adapter.js +110 -24
  3. package/package.json +5 -3
package/CHANGELOG.md CHANGED
@@ -1,4 +1,20 @@
1
1
 
2
+ ## 0.26.6 [03-17-2026]
3
+
4
+ * fix console and bad variable
5
+
6
+ See merge request itentialopensource/adapters/adapter-kafkav2!68
7
+
8
+ ---
9
+
10
+ ## 0.26.5 [03-04-2026]
11
+
12
+ * Changes made at 2026.03.04_09:07AM
13
+
14
+ See merge request itentialopensource/adapters/adapter-kafkav2!67
15
+
16
+ ---
17
+
2
18
  ## 0.26.4 [02-23-2026]
3
19
 
4
20
  * Changes made at 2026.02.22_15:50PM
package/adapter.js CHANGED
@@ -40,7 +40,18 @@ function consoleLoggerProvider(name) {
40
40
  };
41
41
  }
42
42
 
43
- const { Kafka, logLevel } = require('kafkajs');
43
+ // add the compression codecs so that compressed messages can be consumed
44
+ // zstd has an issue in the pipeline
45
+ const {
46
+ Kafka, logLevel, CompressionTypes, CompressionCodecs
47
+ } = require('kafkajs');
48
+ const LZ4 = require('kafka-lz4-lite');
49
+ const SnappyCodec = require('kafkajs-snappy');
50
+ // const ZstdCodec = require('@kafkajs/zstd');
51
+
52
+ CompressionCodecs[CompressionTypes.LZ4] = LZ4.codec;
53
+ CompressionCodecs[CompressionTypes.Snappy] = SnappyCodec;
54
+ // CompressionCodecs[CompressionTypes.ZSTD] = ZstdCodec();
44
55
 
45
56
  const LogLevelEnum = {
46
57
  NOTHING: logLevel.NOTHING,
@@ -232,12 +243,12 @@ function formatErrorObject(origin, type, variables, sysCode, sysRes, stack) {
232
243
  */
233
244
  function createSocketFactory(socketOptions, useSSL) {
234
245
  return (options) => {
235
- console.log('KafkaJS Socket Options:', options); // See what KafkaJS is actually passing
246
+ log.info('KafkaJS Socket Options:', options); // See what KafkaJS is actually passing
236
247
 
237
248
  // Destructure properties from the options object
238
249
  const { host, port, ssl } = options;
239
250
  const brokerAddress = `${host}:${port}`;
240
- console.log(
251
+ log.info(
241
252
  `Connecting to Kafka broker: ${brokerAddress} (${host}:${port}) ${useSSL ? 'with SSL' : 'without SSL'
242
253
  }`
243
254
  );
@@ -259,8 +270,8 @@ function createSocketFactory(socketOptions, useSSL) {
259
270
  socket.setKeepAlive(keepAliveEnabled, keepAliveInterval);
260
271
  socket.setTimeout(socketTimeout);
261
272
 
262
- socket.on('error', (err) => console.error(`Socket error with ${brokerAddress}:`, err));
263
- socket.on('timeout', () => console.warn(`Socket timeout with ${brokerAddress}`));
273
+ socket.on('error', (err) => log.error(`Socket error with ${brokerAddress}:`, err));
274
+ socket.on('timeout', () => log.warn(`Socket timeout with ${brokerAddress}`));
264
275
 
265
276
  return socket;
266
277
  };
@@ -540,6 +551,7 @@ class Kafkav2 extends AdapterBaseCl {
540
551
  this.consumer = null;
541
552
  this.registryUrl = null;
542
553
  this.registry = 'abc';
554
+ this.consumerDisconnecting = false;
543
555
  if (this.props && this.props.registry_url) {
544
556
  this.registryUrl = this.props.registry_url;
545
557
  this.registry = require('avro-schema-registry')(this.props.registry_url);
@@ -763,6 +775,18 @@ class Kafkav2 extends AdapterBaseCl {
763
775
  return matched;
764
776
  };
765
777
 
778
+ // Handle multiple disconnect requests
779
+ const safeConsumerDisconnect = async () => {
780
+ if (this.consumerDisconnecting) return;
781
+ this.consumerDisconnecting = true;
782
+ try {
783
+ await this.consumer.disconnect();
784
+ log.error('Consumer disconnected');
785
+ } catch (_) {
786
+ // ignore disconnect errors during shutdown
787
+ }
788
+ };
789
+
766
790
  const run = async () => {
767
791
  this.emit('ONLINE', {
768
792
  id: this.id
@@ -821,6 +845,30 @@ class Kafkav2 extends AdapterBaseCl {
821
845
  }
822
846
  ));
823
847
 
848
+ // Register a listener for the consumer crash event
849
+ this.consumer.on(this.consumer.events.CRASH, (e) => {
850
+ log.error(`Consumer crashed: ${JSON.stringify(e)}`, e.payload.error.stack);
851
+ setTimeout(() => {
852
+ // process.exit(1); // Or implement a restart mechanism
853
+ throw new Error(JSON.stringify(e));
854
+ }, 1000);
855
+ });
856
+
857
+ // Register a listener for the consumer disconnect event
858
+ this.consumer.on(this.consumer.events.DISCONNECT, (e) => {
859
+ this.consumerDisconnecting = true;
860
+ log.error(`Consumer disconnected: ${JSON.stringify(e)}`);
861
+ setTimeout(() => {
862
+ // process.exit(1); // Or implement a restart mechanism
863
+ throw new Error(JSON.stringify(e));
864
+ }, 1000);
865
+ });
866
+
867
+ // Register a listener for the consumer request_timeout event
868
+ this.consumer.on(this.consumer.events.REQUEST_TIMEOUT, (e) => {
869
+ log.error(`Consumer request timed out: ${JSON.stringify(e)}`);
870
+ });
871
+
824
872
  const runPromise = this.consumer.run({
825
873
  eachMessage: async ({ topic, partition, message }) => {
826
874
  log.info(`PROCESSING NEW MESSAGE ON TOPIC: ${topic} PARTITION: ${partition} WITH OFFSET: ${message.offset}`);
@@ -892,11 +940,11 @@ class Kafkav2 extends AdapterBaseCl {
892
940
  }
893
941
 
894
942
  if (desiredTopic.length !== 0 && allowedPartition) {
895
- log.info(`Message: '${message.value.toString()}' being CONSUMED as it does meet the filter condition`);
943
+ log.info('Message being CONSUMED as it does meet the filter condition');
896
944
  if (desiredTopic.every((val) => mytopics.includes(val))) {
897
945
  log.info(`Emitting: ${message.value.toString()} TO ${desiredTopic}`);
898
946
  } else {
899
- log.info(`The desired topic ${desiredTopic} does not exist. If it should, make sure it is in pronghorn.json`);
947
+ log.warn(`The desired topic ${desiredTopic} does not exist. If it should, make sure it is in pronghorn.json`);
900
948
  log.info(`Emitting: ${newMsg.value.toString()} TO kafka`);
901
949
  desiredTopic = 'kafka';
902
950
  }
@@ -906,16 +954,30 @@ class Kafkav2 extends AdapterBaseCl {
906
954
  try {
907
955
  messageObj = { [wrapper]: JSON.parse(newMsg.value) };
908
956
  } catch (ex) {
909
- messageObj = { [wrapper]: newMsg.value.toString() };
957
+ try {
958
+ messageObj = { [wrapper]: newMsg.value.toString() };
959
+ } catch (excep) {
960
+ log.error(`Failed to wrap message content: ${excep.message}`, excep);
961
+ }
910
962
  }
911
963
  for (let j = 0; j < desiredTopic.length; j += 1) {
912
- messageObj.topic = topic;
913
- eventSystem.publish(desiredTopic[j], messageObj);
964
+ try {
965
+ messageObj.topic = topic;
966
+ eventSystem.publish(desiredTopic[j], messageObj);
967
+ } catch (ex) {
968
+ log.error(`Failed to publish to eventSystem topic '${desiredTopic[j]}': ${ex.message}`, ex);
969
+ log.error(`Failed message content: ${messageObj}`);
970
+ }
914
971
  }
915
972
  } else {
916
973
  for (let j = 0; j < desiredTopic.length; j += 1) {
917
- newMsg.topic = topic;
918
- eventSystem.publish(desiredTopic[j], newMsg);
974
+ try {
975
+ newMsg.topic = topic;
976
+ eventSystem.publish(desiredTopic[j], newMsg);
977
+ } catch (ex) {
978
+ log.error(`Failed to publish to eventSystem topic '${desiredTopic[j]}': ${ex.message}`, ex);
979
+ log.error(`Failed message content: ${newMsg}`);
980
+ }
919
981
  }
920
982
  }
921
983
  } else {
@@ -931,20 +993,27 @@ class Kafkav2 extends AdapterBaseCl {
931
993
 
932
994
  await runPromise;
933
995
  };
934
- run().catch((err) => console.error(`[consumer] ${err.message}`, err));
996
+ run().catch((err) => {
997
+ log.error(`[consumer] ${err.message}`, err);
998
+ throw new Error(JSON.stringify(err));
999
+ });
935
1000
 
936
1001
  const errorTypes = ['unhandledRejection', 'uncaughtException'];
937
1002
  const signalTraps = ['SIGTERM', 'SIGINT', 'SIGUSR2'];
938
1003
 
939
1004
  errorTypes.forEach((type) => {
940
- process.on(type, async (e) => {
1005
+ process.on(type, async (err) => {
941
1006
  try {
942
- console.log(`process.on ${type}`);
943
- console.error(e);
944
- await this.consumer.disconnect();
945
- process.exit(0);
1007
+ log.error(`Kafka Consumer Error - process.on ${type}`);
1008
+ log.error(err, err.stack);
1009
+ await safeConsumerDisconnect();
1010
+ setTimeout(() => {
1011
+ process.exit(0); // Or implement a restart mechanism
1012
+ }, 1000);
946
1013
  } catch (_) {
947
- process.exit(1);
1014
+ setTimeout(() => {
1015
+ process.exit(1); // Or implement a restart mechanism
1016
+ }, 1000);
948
1017
  }
949
1018
  });
950
1019
  });
@@ -952,7 +1021,7 @@ class Kafkav2 extends AdapterBaseCl {
952
1021
  signalTraps.forEach((type) => {
953
1022
  process.once(type, async () => {
954
1023
  try {
955
- await this.consumer.disconnect();
1024
+ await safeConsumerDisconnect();
956
1025
  } finally {
957
1026
  process.kill(process.pid, type);
958
1027
  }
@@ -1030,6 +1099,11 @@ class Kafkav2 extends AdapterBaseCl {
1030
1099
 
1031
1100
  const run = async () => {
1032
1101
  try {
1102
+ // Register a listener for the producer request_timeout event
1103
+ this.producer.on(this.producer.events.REQUEST_TIMEOUT, (e) => {
1104
+ log.error(`Producer request timed out: ${JSON.stringify(e)}`);
1105
+ });
1106
+
1033
1107
  const topicMessages = payloads;
1034
1108
  // need to go through the payloads that were provided
1035
1109
  for (let p = 0; p < payloads.length; p += 1) {
@@ -1043,12 +1117,18 @@ class Kafkav2 extends AdapterBaseCl {
1043
1117
  log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1044
1118
  return callback(null, errorObj);
1045
1119
  }
1120
+ if (!Array.isArray(payloads[p].messages)) {
1121
+ const errorObj = formatErrorObject(origin, 'Invalid payloads format - messages must be an array', null, null, null, null);
1122
+ log.error(`${origin}: ${errorObj.IAPerror.displayString}`);
1123
+ return callback(null, errorObj);
1124
+ }
1046
1125
  topicMessages[p].messages = payloads[p].messages.map((message) => {
1047
1126
  if (typeof message.value === 'object') {
1048
1127
  return { ...message, value: JSON.stringify(message.value) };
1049
1128
  }
1050
1129
  return message;
1051
1130
  });
1131
+ log.debug(`Sending message(s) to topic: ${payloads[p].topic}`);
1052
1132
  if (this.registry && topicMessages[p].simple && topicMessages[p].simple.toUpperCase() === 'NO') {
1053
1133
  log.debug(`Handling AVRO Message: ${JSON.stringify(topicMessages[p])}`);
1054
1134
  let keyVer = 1;
@@ -1113,6 +1193,7 @@ class Kafkav2 extends AdapterBaseCl {
1113
1193
  }
1114
1194
  await this.producer.connect();
1115
1195
  await this.producer.sendBatch({ topicMessages });
1196
+ log.debug(`Sent message to broker: ${JSON.stringify(topicMessages)}`);
1116
1197
  } catch (err) {
1117
1198
  const errorObj = formatErrorObject(origin, 'Producer sending message failed', null, null, null, err);
1118
1199
  log.error('error: '.concat(err));
@@ -1130,13 +1211,18 @@ class Kafkav2 extends AdapterBaseCl {
1130
1211
  const signalTraps = ['SIGTERM', 'SIGINT', 'SIGUSR2'];
1131
1212
 
1132
1213
  errorTypes.forEach((type) => {
1133
- process.on(type, async () => {
1214
+ process.on(type, async (err) => {
1134
1215
  try {
1135
- console.log(`process.on ${type}`);
1216
+ log.error(`Kafka Producer Error - process.on ${type}`);
1217
+ log.error(err, err.stack);
1136
1218
  await this.producer.disconnect();
1137
- process.exit(0);
1219
+ setTimeout(() => {
1220
+ process.exit(0); // Or implement a restart mechanism
1221
+ }, 1000);
1138
1222
  } catch (_) {
1139
- process.exit(1);
1223
+ setTimeout(() => {
1224
+ process.exit(1); // Or implement a restart mechanism
1225
+ }, 1000);
1140
1226
  }
1141
1227
  });
1142
1228
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itentialopensource/adapter-kafkav2",
3
- "version": "0.26.4",
3
+ "version": "0.26.6",
4
4
  "description": "Itential adapter to connect to kafka",
5
5
  "main": "adapter.js",
6
6
  "scripts": {
@@ -40,10 +40,12 @@
40
40
  "ajv": "8.18.0",
41
41
  "avro-schema-registry": "2.1.0",
42
42
  "avsc": "5.4.21",
43
- "axios": "1.13.5",
43
+ "axios": "1.13.6",
44
44
  "fs-extra": "11.3.3",
45
45
  "json-query": "2.2.2",
46
- "kafkajs": "2.2.3",
46
+ "kafkajs": "2.2.4",
47
+ "kafka-lz4-lite": "1.0.5",
48
+ "kafkajs-snappy": "1.1.0",
47
49
  "mongodb": "4.17.2",
48
50
  "readline-sync": "1.4.10",
49
51
  "uuid": "3.0.1",