@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 +3 -1
- package/package.json +3 -3
- package/src/index.js +4 -1
- package/src/orchestration/waitForInfrastructureReady.js +0 -142
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
|
-
- `
|
|
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.
|
|
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.
|
|
22
|
-
"
|
|
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
|
-
|
|
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
|
-
|