@onlineapps/infrastructure-tools 1.0.2 → 1.0.4

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
@@ -55,6 +55,8 @@ await waitForInfrastructureReady({
55
55
  });
56
56
  ```
57
57
 
58
+ **Note:** `waitForInfrastructureReady` is re-exported from `@onlineapps/service-common` to avoid duplication. Both infrastructure and business services can use it.
59
+
58
60
  ### Initialize Infrastructure Queues
59
61
 
60
62
  Initialize infrastructure queues with correct parameters:
@@ -120,7 +122,7 @@ Creates health publisher adapter for amqplib (direct connection + channel).
120
122
  ## Dependencies
121
123
 
122
124
  - `@onlineapps/mq-client-core` - For queue configuration
123
- - `redis` - For health status checking
125
+ - `@onlineapps/service-common` - For `waitForInfrastructureReady` (shared utility)
124
126
 
125
127
  ## Related Libraries
126
128
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/infrastructure-tools",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Infrastructure orchestration utilities for OA Drive infrastructure services (health tracking, queue initialization, service discovery)",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -18,8 +18,8 @@
18
18
  "author": "OnlineApps",
19
19
  "license": "MIT",
20
20
  "dependencies": {
21
- "@onlineapps/mq-client-core": "^1.0.24",
22
- "redis": "^4.6.0"
21
+ "@onlineapps/mq-client-core": "^1.0.25",
22
+ "@onlineapps/service-common": "^1.0.0"
23
23
  },
24
24
  "devDependencies": {
25
25
  "jest": "^29.7.0"
package/src/index.js CHANGED
@@ -10,7 +10,9 @@
10
10
  * Business services should NOT use this library.
11
11
  */
12
12
 
13
- const { waitForInfrastructureReady } = require('./orchestration/waitForInfrastructureReady');
13
+ // Re-export waitForInfrastructureReady from service-common (no duplication)
14
+ const { waitForInfrastructureReady } = require('@onlineapps/service-common');
15
+
14
16
  const { initInfrastructureQueues } = require('./orchestration/initInfrastructureQueues');
15
17
  const {
16
18
  createHealthPublisher,
@@ -20,6 +22,7 @@ const {
20
22
 
21
23
  module.exports = {
22
24
  // Orchestration utilities
25
+ // waitForInfrastructureReady is re-exported from @onlineapps/service-common
23
26
  waitForInfrastructureReady,
24
27
  initInfrastructureQueues,
25
28
 
@@ -1,142 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * waitForInfrastructureReady.js
5
- *
6
- * Waits for all infrastructure services to be verified as running and healthy.
7
- * Used by infrastructure services before creating queues to ensure system consistency.
8
- *
9
- * This prevents race conditions where queues are created before all services are ready.
10
- *
11
- * **How it works:**
12
- * 1. Connects to Redis (where Registry stores infrastructure health status)
13
- * 2. Checks `infrastructure:health:all` key every 5 seconds
14
- * 3. If key is `"true"` → all infrastructure services are UP → return success
15
- * 4. If key is `"false"` or missing → wait and retry
16
- * 5. If timeout reached → throw error
17
- *
18
- * **Why Redis (not HTTP):**
19
- * - Fast: In-memory lookup, no network overhead
20
- * - Reliable: Redis is already required infrastructure
21
- * - Low latency: Direct key lookup, no HTTP parsing
22
- * - Consistent: Same data source as Registry uses
23
- * - No single point of failure: Redis can be clustered
24
- */
25
-
26
- /**
27
- * Wait for all infrastructure services to be ready
28
- * @param {Object} options - Options
29
- * @param {string} [options.redisUrl] - Redis URL (default: REDIS_URL env or redis://api_node_cache:6379)
30
- * @param {number} [options.maxWait] - Maximum wait time in ms (default: INFRASTRUCTURE_HEALTH_WAIT_MAX_TIME env or 300000 = 5 minutes)
31
- * @param {number} [options.checkInterval] - Check interval in ms (default: INFRASTRUCTURE_HEALTH_WAIT_CHECK_INTERVAL env or 5000 = 5 seconds)
32
- * @param {Object} [options.logger] - Logger instance (default: console)
33
- * @returns {Promise<boolean>} - True if all infrastructure services are ready
34
- * @throws {Error} - If timeout is reached
35
- *
36
- * Note: Default values can be overridden via ENV variables or options parameter.
37
- * Registry config (config.infrastructureHealth) is the source of truth for these defaults.
38
- */
39
- async function waitForInfrastructureReady(options = {}) {
40
- const redisUrl = options.redisUrl || process.env.REDIS_URL || 'redis://api_node_cache:6379';
41
- const maxWait = options.maxWait || parseInt(process.env.INFRASTRUCTURE_HEALTH_WAIT_MAX_TIME) || 300000; // 5 minutes
42
- const checkInterval = options.checkInterval || parseInt(process.env.INFRASTRUCTURE_HEALTH_WAIT_CHECK_INTERVAL) || 5000; // 5 seconds
43
- const logger = options.logger || console;
44
-
45
- // Universal logger adapter (supports both console and winston)
46
- // Winston logger expects object with message property, console.log accepts string
47
- const log = (message) => {
48
- if (typeof logger.info === 'function' && typeof logger.log !== 'function') {
49
- // Likely winston logger - use object format
50
- logger.info({ message: String(message) });
51
- } else if (typeof logger.log === 'function') {
52
- // console.log or similar
53
- logger.log(message);
54
- } else if (typeof logger.info === 'function') {
55
- // Fallback for other loggers
56
- logger.info(message);
57
- } else {
58
- console.log(message);
59
- }
60
- };
61
-
62
- const startTime = Date.now();
63
- let attemptCount = 0;
64
- let redis = null;
65
-
66
- log('[InfrastructureReady] Waiting for all infrastructure services to be ready...');
67
- log(`[InfrastructureReady] Redis URL: ${redisUrl}`);
68
- log(`[InfrastructureReady] Max wait: ${maxWait}ms, Check interval: ${checkInterval}ms`);
69
-
70
- try {
71
- // Connect to Redis
72
- const { createClient } = require('redis');
73
- redis = createClient({ url: redisUrl });
74
-
75
- redis.on('error', (err) => {
76
- log(`[InfrastructureReady] Redis error: ${err.message}`);
77
- });
78
-
79
- await redis.connect();
80
- log('[InfrastructureReady] Connected to Redis');
81
-
82
- while (Date.now() - startTime < maxWait) {
83
- attemptCount++;
84
-
85
- try {
86
- // Check Redis key: infrastructure:health:all
87
- const allHealthy = await redis.get('infrastructure:health:all');
88
-
89
- if (allHealthy === 'true') {
90
- // All services are UP, we can proceed
91
- const elapsed = Date.now() - startTime;
92
- log(`[InfrastructureReady] ✓ All infrastructure services are ready (took ${elapsed}ms, ${attemptCount} attempts)`);
93
-
94
- // Optionally log individual service status
95
- // Note: Service names should match config.infrastructureServices in Registry
96
- const serviceKeys = ['gateway', 'registry', 'validator', 'delivery', 'monitoring'];
97
- const statuses = {};
98
- for (const serviceName of serviceKeys) {
99
- const status = await redis.get(`infrastructure:health:${serviceName}`);
100
- if (status) {
101
- statuses[serviceName] = JSON.parse(status);
102
- }
103
- }
104
- log(`[InfrastructureReady] Infrastructure status: ${JSON.stringify(statuses, null, 2)}`);
105
-
106
- return true;
107
- }
108
-
109
- // Not all services ready yet
110
- log(`[InfrastructureReady] Attempt ${attemptCount}: Not all services ready (allHealthy: ${allHealthy || 'null'})`);
111
- log(`[InfrastructureReady] Waiting ${checkInterval}ms before next check...`);
112
-
113
- } catch (error) {
114
- // Redis might not be ready yet, or connection issue
115
- log(`[InfrastructureReady] Attempt ${attemptCount}: Redis check failed (${error.message})`);
116
- log(`[InfrastructureReady] Waiting ${checkInterval}ms before retry...`);
117
- }
118
-
119
- // Wait before next check
120
- await new Promise(resolve => setTimeout(resolve, checkInterval));
121
- }
122
-
123
- // Timeout reached
124
- const elapsed = Date.now() - startTime;
125
- throw new Error(
126
- `Infrastructure services not ready within ${maxWait}ms (${elapsed}ms elapsed, ${attemptCount} attempts). ` +
127
- `Check Redis keys: infrastructure:health:*`
128
- );
129
-
130
- } finally {
131
- // Clean up Redis connection
132
- if (redis && redis.isReady) {
133
- await redis.quit();
134
- log('[InfrastructureReady] Redis connection closed');
135
- }
136
- }
137
- }
138
-
139
- module.exports = {
140
- waitForInfrastructureReady
141
- };
142
-