sentinel-kafka-manager 1.0.1 → 1.0.3

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 (2) hide show
  1. package/README.md +349 -83
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -48,6 +48,350 @@ npm run build
48
48
  - Kafka cluster reachable from the service
49
49
  - `kafkajs` is included automatically as a dependency of this package
50
50
 
51
+ ## Full Service Example
52
+
53
+ ```ts
54
+ import { KafkaManager } from 'sentinel-kafka-manager'
55
+
56
+ const kafkaManager = KafkaManager.fromEnv({
57
+ clientId: 'claims-api',
58
+ mode: 'external',
59
+ })
60
+
61
+ async function bootstrap(): Promise<void> {
62
+ await kafkaManager.provisionTopics([
63
+ {
64
+ topic: 'claims.created',
65
+ numPartitions: 6,
66
+ replicationFactor: 3,
67
+ },
68
+ ])
69
+
70
+ await kafkaManager.publish({
71
+ topic: 'claims.created',
72
+ key: 'claim-1001',
73
+ payload: {
74
+ claimId: 'claim-1001',
75
+ source: 'claims-api',
76
+ },
77
+ })
78
+
79
+ await kafkaManager.runConsumer({
80
+ groupId: 'claims-api-group',
81
+ topic: 'claims.created',
82
+ dlqTopic: 'claims.created.dlq',
83
+ onMessage: async ({ message, headers }) => {
84
+ console.log('Received event:', {
85
+ traceId: headers['x-trace-id'],
86
+ payload: message,
87
+ })
88
+ },
89
+ })
90
+ }
91
+
92
+ bootstrap().catch(async (error) => {
93
+ console.error('Kafka bootstrap failed:', error)
94
+ await kafkaManager.disconnect()
95
+ process.exit(1)
96
+ })
97
+
98
+ process.on('SIGINT', async () => {
99
+ await kafkaManager.disconnect()
100
+ process.exit(0)
101
+ })
102
+
103
+ process.on('SIGTERM', async () => {
104
+ await kafkaManager.disconnect()
105
+ process.exit(0)
106
+ })
107
+ ```
108
+
109
+ ## Create A Kafka Server With This Repo
110
+
111
+ This repository already includes a full local Kafka server setup in [docker-compose.yml](/var/www/html/matrix-project/sentinel-kafka-manager/docker-compose.yml) and sample environment values in [.env.local.example](/var/www/html/matrix-project/sentinel-kafka-manager/.env.local.example).
112
+
113
+ The stack includes:
114
+
115
+ - 3 KRaft controllers
116
+ - 3 Kafka brokers
117
+ - 1 Kafka UI instance
118
+
119
+ ### 1. Create your `.env`
120
+
121
+ Copy the example file:
122
+
123
+ ```bash
124
+ cp .env.local.example .env
125
+ ```
126
+
127
+ If you want a standard localhost setup, the example values are already suitable.
128
+
129
+ ### 2. Start the Kafka cluster
130
+
131
+ ```bash
132
+ docker compose --env-file .env up -d
133
+ ```
134
+
135
+ This creates:
136
+
137
+ - controller quorum on port `9093` inside Docker
138
+ - internal broker traffic on port `9092` inside Docker
139
+ - host-accessible broker ports `29092`, `39092`, and `49092`
140
+ - Kafka UI on `127.0.0.1:5001`
141
+
142
+ ### 3. Stop the Kafka cluster
143
+
144
+ ```bash
145
+ docker compose --env-file .env down
146
+ ```
147
+
148
+ To also remove persisted Kafka data volumes:
149
+
150
+ ```bash
151
+ docker compose --env-file .env down -v
152
+ ```
153
+
154
+ ### 4. Check container status
155
+
156
+ ```bash
157
+ docker compose --env-file .env ps
158
+ ```
159
+
160
+ ### 5. Current broker endpoints
161
+
162
+ For applications running on your host machine:
163
+
164
+ ```text
165
+ localhost:29092
166
+ localhost:39092
167
+ localhost:49092
168
+ ```
169
+
170
+ For applications running inside Docker on the same Compose network:
171
+
172
+ ```text
173
+ broker-1:9092
174
+ broker-2:9092
175
+ broker-3:9092
176
+ ```
177
+
178
+ Important:
179
+
180
+ - application clients must connect to brokers, not controllers
181
+ - controllers are internal cluster metadata nodes only
182
+ - `mode: 'external'` is for host-based apps
183
+ - `mode: 'internal'` is for Dockerized apps on the same network
184
+
185
+ ## Kafka UI Usage
186
+
187
+ The Docker stack also starts Kafka UI for cluster inspection.
188
+
189
+ ### Open the UI
190
+
191
+ Visit:
192
+
193
+ ```text
194
+ http://127.0.0.1:5001
195
+ ```
196
+
197
+ ### Login credentials
198
+
199
+ By default, the UI uses the credentials from `.env`:
200
+
201
+ ```env
202
+ KAFKA_UI_USERNAME=admin
203
+ KAFKA_UI_PASSWORD=Admin@007
204
+ ```
205
+
206
+ ### What the UI connects to
207
+
208
+ Kafka UI is preconfigured in `docker-compose.yml` to use all three brokers:
209
+
210
+ ```text
211
+ broker-1:9092,broker-2:9092,broker-3:9092
212
+ ```
213
+
214
+ The cluster name shown in the UI comes from:
215
+
216
+ ```env
217
+ KAFKA_UI_CLUSTER_NAME=Project Omni Enterprise Kafka
218
+ ```
219
+
220
+ ### What you can do in the UI
221
+
222
+ - view brokers and cluster health
223
+ - inspect topics and partitions
224
+ - browse messages
225
+ - inspect consumer groups
226
+ - check offsets and lag
227
+
228
+ ### Read-only mode
229
+
230
+ The example `.env` sets:
231
+
232
+ ```env
233
+ KAFKA_UI_READONLY=true
234
+ ```
235
+
236
+ That means the UI is intended for safe inspection only.
237
+
238
+ If you want to create topics or make changes from the UI, change it to:
239
+
240
+ ```env
241
+ KAFKA_UI_READONLY=false
242
+ ```
243
+
244
+ Then restart the stack:
245
+
246
+ ```bash
247
+ docker compose --env-file .env up -d
248
+ ```
249
+
250
+ ### Typical UI flow
251
+
252
+ 1. Start the Docker stack.
253
+ 2. Open `http://127.0.0.1:5001`.
254
+ 3. Log in with `KAFKA_UI_USERNAME` and `KAFKA_UI_PASSWORD`.
255
+ 4. Open the configured cluster.
256
+ 5. Go to Topics, Consumer Groups, or Brokers as needed.
257
+
258
+ ## Docker Compose And `.env` Reference
259
+
260
+ This project does not use a separate `Dockerfile` for Kafka. The Kafka server is created from `docker-compose.yml` and environment values from `.env`.
261
+
262
+ ### Core Kafka image and cluster identity
263
+
264
+ ```env
265
+ KAFKA_IMAGE=confluentinc/cp-kafka:7.6.6
266
+ KAFKA_CLUSTER_ID=MkU3OEVBNTcwNTJENDM2Qk
267
+ KAFKA_RESTART_POLICY=unless-stopped
268
+ KAFKA_STOP_GRACE_PERIOD=60s
269
+ KAFKA_NETWORK_NAME=kafka-network
270
+ ```
271
+
272
+ - `KAFKA_IMAGE`: Kafka container image used by controllers and brokers
273
+ - `KAFKA_CLUSTER_ID`: shared KRaft cluster id for all nodes
274
+ - `KAFKA_NETWORK_NAME`: Docker network name used by the full stack
275
+
276
+ ### Controller quorum settings
277
+
278
+ ```env
279
+ KAFKA_CONTROLLER_PORT=9093
280
+ KAFKA_CONTROLLER_LISTENER_NAMES=CONTROLLER
281
+ KAFKA_CONTROLLER_QUORUM_VOTERS=1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
282
+ ```
283
+
284
+ - controllers run only inside Docker
285
+ - apps should never use these controller addresses as Kafka client brokers
286
+
287
+ ### Broker listener settings
288
+
289
+ ```env
290
+ KAFKA_BROKER_BIND_ADDRESS=0.0.0.0
291
+ KAFKA_EXTERNAL_HOST=localhost
292
+ KAFKA_BROKER_INTERNAL_PORT=9092
293
+ KAFKA_BROKER_EXTERNAL_CONTAINER_PORT=19092
294
+ KAFKA_BROKER_1_EXTERNAL_PORT=29092
295
+ KAFKA_BROKER_2_EXTERNAL_PORT=39092
296
+ KAFKA_BROKER_3_EXTERNAL_PORT=49092
297
+ KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL
298
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
299
+ ```
300
+
301
+ - `KAFKA_EXTERNAL_HOST=localhost` exposes brokers to your host machine
302
+ - `KAFKA_BROKER_1_EXTERNAL_PORT`, `KAFKA_BROKER_2_EXTERNAL_PORT`, and `KAFKA_BROKER_3_EXTERNAL_PORT` are the ports your local apps should use
303
+ - `KAFKA_BROKER_INTERNAL_PORT=9092` is used by containers on the Docker network
304
+
305
+ ### Replication and durability defaults
306
+
307
+ ```env
308
+ KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=3
309
+ KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
310
+ KAFKA_TRANSACTION_STATE_LOG_MIN_ISR=2
311
+ KAFKA_DEFAULT_REPLICATION_FACTOR=3
312
+ KAFKA_MIN_INSYNC_REPLICAS=2
313
+ KAFKA_NUM_PARTITIONS=6
314
+ ```
315
+
316
+ These values are designed for the included three-broker cluster.
317
+
318
+ ### Broker behavior
319
+
320
+ ```env
321
+ KAFKA_AUTO_CREATE_TOPICS_ENABLE=false
322
+ KAFKA_DELETE_TOPIC_ENABLE=true
323
+ KAFKA_LOG_RETENTION_HOURS=168
324
+ KAFKA_LOG_SEGMENT_BYTES=1073741824
325
+ KAFKA_MESSAGE_MAX_BYTES=10485880
326
+ KAFKA_REPLICA_FETCH_MAX_BYTES=10485880
327
+ KAFKA_SOCKET_REQUEST_MAX_BYTES=104857600
328
+ ```
329
+
330
+ - topics are not auto-created by default
331
+ - deleting topics is allowed
332
+ - retention is 7 days by default
333
+
334
+ ### Storage and safety limits
335
+
336
+ ```env
337
+ KAFKA_LOG_DIRS=/var/lib/kafka/data
338
+ KAFKA_ULIMIT_NOFILE_SOFT=65536
339
+ KAFKA_ULIMIT_NOFILE_HARD=65536
340
+ KAFKA_LOG_MAX_SIZE=100m
341
+ KAFKA_LOG_MAX_FILE=5
342
+ ```
343
+
344
+ ### Kafka UI settings
345
+
346
+ ```env
347
+ KAFKA_UI_IMAGE=provectuslabs/kafka-ui:latest
348
+ KAFKA_UI_CONTAINER_NAME=kafka-ui
349
+ KAFKA_UI_HOSTNAME=kafka-ui
350
+ KAFKA_UI_RESTART_POLICY=unless-stopped
351
+ KAFKA_UI_BIND_ADDRESS=127.0.0.1
352
+ KAFKA_UI_PORT=5001
353
+ KAFKA_UI_DYNAMIC_CONFIG_ENABLED=false
354
+ KAFKA_UI_CLUSTER_NAME=Project Omni Enterprise Kafka
355
+ KAFKA_UI_READONLY=true
356
+ KAFKA_UI_AUTH_TYPE=LOGIN_FORM
357
+ KAFKA_UI_USERNAME=admin
358
+ KAFKA_UI_PASSWORD=Admin@007
359
+ ```
360
+
361
+ - `KAFKA_UI_BIND_ADDRESS=127.0.0.1` keeps the UI local-only
362
+ - `KAFKA_UI_PORT=5001` publishes the UI on your machine
363
+ - `KAFKA_UI_READONLY=true` prevents write actions from the UI
364
+
365
+ ### Healthcheck settings
366
+
367
+ ```env
368
+ KAFKA_HEALTHCHECK_INTERVAL=10s
369
+ KAFKA_HEALTHCHECK_TIMEOUT=5s
370
+ KAFKA_HEALTHCHECK_RETRIES=15
371
+ KAFKA_HEALTHCHECK_START_PERIOD=30s
372
+ ```
373
+
374
+ ## Creating Topics
375
+
376
+ Because `KAFKA_AUTO_CREATE_TOPICS_ENABLE=false`, topics should be created deliberately.
377
+
378
+ You have two good options:
379
+
380
+ - create topics from your service with `kafkaManager.provisionTopics()`
381
+ - allow UI-based creation by setting `KAFKA_UI_READONLY=false`
382
+
383
+ Example with this package:
384
+
385
+ ```ts
386
+ await kafkaManager.provisionTopics([
387
+ {
388
+ topic: 'claims.created',
389
+ numPartitions: 6,
390
+ replicationFactor: 3,
391
+ },
392
+ ])
393
+ ```
394
+
51
395
  ## Enterprise Features
52
396
 
53
397
  This version now includes a stronger production baseline:
@@ -544,64 +888,6 @@ const kafkaManager = KafkaManager.fromEnv({
544
888
 
545
889
  This package is designed to work with that exact broker layout.
546
890
 
547
- ## Full Service Example
548
-
549
- ```ts
550
- import { KafkaManager } from 'sentinel-kafka-manager'
551
-
552
- const kafkaManager = KafkaManager.fromEnv({
553
- clientId: 'claims-api',
554
- mode: 'external',
555
- })
556
-
557
- async function bootstrap(): Promise<void> {
558
- await kafkaManager.provisionTopics([
559
- {
560
- topic: 'claims.created',
561
- numPartitions: 6,
562
- replicationFactor: 3,
563
- },
564
- ])
565
-
566
- await kafkaManager.publish({
567
- topic: 'claims.created',
568
- key: 'claim-1001',
569
- payload: {
570
- claimId: 'claim-1001',
571
- source: 'claims-api',
572
- },
573
- })
574
-
575
- await kafkaManager.runConsumer({
576
- groupId: 'claims-api-group',
577
- topic: 'claims.created',
578
- dlqTopic: 'claims.created.dlq',
579
- onMessage: async ({ message, headers }) => {
580
- console.log('Received event:', {
581
- traceId: headers['x-trace-id'],
582
- payload: message,
583
- })
584
- },
585
- })
586
- }
587
-
588
- bootstrap().catch(async (error) => {
589
- console.error('Kafka bootstrap failed:', error)
590
- await kafkaManager.disconnect()
591
- process.exit(1)
592
- })
593
-
594
- process.on('SIGINT', async () => {
595
- await kafkaManager.disconnect()
596
- process.exit(0)
597
- })
598
-
599
- process.on('SIGTERM', async () => {
600
- await kafkaManager.disconnect()
601
- process.exit(0)
602
- })
603
- ```
604
-
605
891
  ## API Summary
606
892
 
607
893
  ### `new KafkaManager(options)`
@@ -874,31 +1160,6 @@ For most SaaS services, the cleanest pattern is:
874
1160
  5. Catch `KafkaManagerError` and branch on `error.code`.
875
1161
  6. Wrap service outcomes in `OperationResponse<T>` where useful.
876
1162
 
877
- ## Publishing This Package
878
-
879
- Build:
880
-
881
- ```bash
882
- npm run build
883
- ```
884
-
885
- Publish:
886
-
887
- ```bash
888
- npm publish
889
- ```
890
-
891
- If npm rejects the publish:
892
-
893
- - `403` usually means authentication, 2FA, or token permission issues
894
- - `404` usually means the package name is unavailable or not publishable by your account
895
-
896
- Useful check:
897
-
898
- ```bash
899
- npm whoami
900
- ```
901
-
902
1163
  ## Notes
903
1164
 
904
1165
  - Your current Kafka cluster works fine with PLAINTEXT, so SSL and SASL are optional unless your environment changes
@@ -907,6 +1168,11 @@ npm whoami
907
1168
 
908
1169
  ## Links
909
1170
 
1171
+ - npm deployment guide: [NPM_DEPLOYMENT.md](/var/www/html/matrix-project/sentinel-kafka-manager/NPM_DEPLOYMENT.md)
1172
+ - Example folder: [examples/service-module-usage/README.md](/var/www/html/matrix-project/sentinel-kafka-manager/examples/service-module-usage/README.md)
1173
+ - Service module guide: [SERVICE_MODULE_USAGE.md](/var/www/html/matrix-project/sentinel-kafka-manager/SERVICE_MODULE_USAGE.md)
1174
+ - GitHub: https://github.com/dilipshaw2024/sentinel-kafka-manager
1175
+ - npm: https://www.npmjs.com/package/sentinel-kafka-manager
910
1176
  - LinkedIn: https://www.linkedin.com/in/dilip-shaw-2740769/
911
1177
 
912
1178
  ## About Me
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sentinel-kafka-manager",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Reusable Kafka manager for Node.js microservices",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",