@onlineapps/conn-orch-registry 1.1.22 → 1.1.23
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/package.json +2 -1
- package/src/queueManager.js +11 -40
- package/src/registryClient.js +51 -116
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlineapps/conn-orch-registry",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.23",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Connector-registry-client provides the core communication mechanism for microservices in this environment. It enables them to interact with a services_registry to receive and fulfill tasks by submitting heartbeats or their API descriptions.",
|
|
6
6
|
"keywords": [
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@onlineapps/conn-base-storage": "^1.0.0",
|
|
42
|
+
"@onlineapps/mq-client-core": "^1.0.26",
|
|
42
43
|
"amqplib": "^0.10.9",
|
|
43
44
|
"axios": "^1.12.2",
|
|
44
45
|
"dotenv": "^16.6.1",
|
package/src/queueManager.js
CHANGED
|
@@ -19,15 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
const amqp = require('amqplib');
|
|
22
|
-
|
|
23
|
-
// This prevents 406 PRECONDITION-FAILED errors from TTL mismatches
|
|
24
|
-
let queueConfig;
|
|
25
|
-
try {
|
|
26
|
-
queueConfig = require('@onlineapps/conn-infra-mq/src/config/queueConfig');
|
|
27
|
-
} catch (err) {
|
|
28
|
-
console.warn('[QueueManager] [REGISTRY] queueConfig not available, using defaults:', err.message);
|
|
29
|
-
queueConfig = null;
|
|
30
|
-
}
|
|
22
|
+
const queueConfig = require('@onlineapps/mq-client-core/src/config/queueConfig');
|
|
31
23
|
|
|
32
24
|
/**
|
|
33
25
|
* Queue manager for the microservice connector.
|
|
@@ -68,10 +60,7 @@ class QueueManager {
|
|
|
68
60
|
}
|
|
69
61
|
|
|
70
62
|
// Default queues for the registry client
|
|
71
|
-
const baseQueues = [
|
|
72
|
-
'workflow'
|
|
73
|
-
// Note: ${serviceName}.registry queue is created by RegistryEventConsumer when needed
|
|
74
|
-
];
|
|
63
|
+
const baseQueues = [];
|
|
75
64
|
|
|
76
65
|
const queuesToCreate = baseQueues.concat(additionalQueues);
|
|
77
66
|
|
|
@@ -101,34 +90,16 @@ class QueueManager {
|
|
|
101
90
|
console.warn(`[QueueManager] [REGISTRY] [QUEUE] queueConfig not available, using default options for ${q}`);
|
|
102
91
|
}
|
|
103
92
|
|
|
104
|
-
//
|
|
105
|
-
// If queue doesn't exist (404), then assertQueue to create it with correct options
|
|
93
|
+
// Directly assert queue with canonical configuration (idempotent)
|
|
106
94
|
try {
|
|
107
|
-
const
|
|
108
|
-
await this.channel.
|
|
109
|
-
const
|
|
110
|
-
console.log(`[QueueManager] [REGISTRY] [QUEUE] ✓ Queue ${q}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
console.log(`[QueueManager] [REGISTRY] [QUEUE] Queue ${q} does not exist (404), creating with options:`, JSON.stringify(queueOptions));
|
|
116
|
-
const assertStartTime = Date.now();
|
|
117
|
-
try {
|
|
118
|
-
await this.channel.assertQueue(q, queueOptions);
|
|
119
|
-
const assertEndTime = Date.now();
|
|
120
|
-
console.log(`[QueueManager] [REGISTRY] [QUEUE] ✓ Created queue ${q} (assertQueue took ${assertEndTime - assertStartTime}ms)`);
|
|
121
|
-
} catch (assertErr) {
|
|
122
|
-
console.error(`[QueueManager] [REGISTRY] [QUEUE] ✗ Failed to create queue ${q}:`, assertErr.message);
|
|
123
|
-
console.error(`[QueueManager] [REGISTRY] [QUEUE] Error code: ${assertErr.code}`);
|
|
124
|
-
throw assertErr;
|
|
125
|
-
}
|
|
126
|
-
} else {
|
|
127
|
-
// Other error (including 406) - queue exists with different args
|
|
128
|
-
// Log warning and continue without asserting
|
|
129
|
-
console.warn(`[QueueManager] [REGISTRY] [QUEUE] Queue ${q} exists with different arguments, using as-is:`, checkErr.message);
|
|
130
|
-
console.warn(`[QueueManager] [REGISTRY] [QUEUE] Error code: ${checkErr.code}`);
|
|
131
|
-
}
|
|
95
|
+
const assertStartTime = Date.now();
|
|
96
|
+
await this.channel.assertQueue(q, queueOptions);
|
|
97
|
+
const assertEndTime = Date.now();
|
|
98
|
+
console.log(`[QueueManager] [REGISTRY] [QUEUE] ✓ Queue ${q} asserted (took ${assertEndTime - assertStartTime}ms)`);
|
|
99
|
+
} catch (assertErr) {
|
|
100
|
+
console.error(`[QueueManager] [REGISTRY] [QUEUE] ✗ Failed to assert queue ${q}:`, assertErr.message);
|
|
101
|
+
console.error(`[QueueManager] [REGISTRY] [QUEUE] Error code: ${assertErr.code}`);
|
|
102
|
+
throw assertErr;
|
|
132
103
|
}
|
|
133
104
|
}
|
|
134
105
|
}
|
package/src/registryClient.js
CHANGED
|
@@ -19,46 +19,8 @@ const EventEmitter = require('events');
|
|
|
19
19
|
const QueueManager = require('./queueManager');
|
|
20
20
|
const RegistryEventConsumer = require('./registryEventConsumer');
|
|
21
21
|
const { v4: uuidv4 } = require('uuid');
|
|
22
|
+
const queueConfig = require('@onlineapps/mq-client-core/src/config/queueConfig');
|
|
22
23
|
|
|
23
|
-
// CRITICAL: Import queueConfig to ensure consistent queue parameters
|
|
24
|
-
// This prevents 406 PRECONDITION-FAILED errors from TTL mismatches
|
|
25
|
-
let queueConfig;
|
|
26
|
-
try {
|
|
27
|
-
queueConfig = require('@onlineapps/conn-infra-mq/src/config/queueConfig');
|
|
28
|
-
} catch (err) {
|
|
29
|
-
console.warn('[RegistryClient] queueConfig not available, using defaults:', err.message);
|
|
30
|
-
queueConfig = null;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Helper function to get queue options from queueConfig.js
|
|
35
|
-
* @param {string} queueName - Queue name
|
|
36
|
-
* @returns {Object} Queue options with correct parameters (TTL, max-length, etc.)
|
|
37
|
-
*/
|
|
38
|
-
function getQueueOptions(queueName) {
|
|
39
|
-
let queueOptions = { durable: true };
|
|
40
|
-
|
|
41
|
-
if (queueConfig) {
|
|
42
|
-
try {
|
|
43
|
-
if (queueConfig.isInfrastructureQueue(queueName)) {
|
|
44
|
-
const infraConfig = queueConfig.getInfrastructureQueueConfig(queueName);
|
|
45
|
-
queueOptions = {
|
|
46
|
-
durable: infraConfig.durable !== false,
|
|
47
|
-
arguments: { ...infraConfig.arguments }
|
|
48
|
-
};
|
|
49
|
-
console.log(`[RegistryClient] [QUEUE] Using infrastructure queue config for ${queueName}:`, JSON.stringify(queueOptions));
|
|
50
|
-
} else {
|
|
51
|
-
console.warn(`[RegistryClient] [QUEUE] Queue ${queueName} is not an infrastructure queue, using default options`);
|
|
52
|
-
}
|
|
53
|
-
} catch (configErr) {
|
|
54
|
-
console.warn(`[RegistryClient] [QUEUE] Failed to get config for ${queueName}, using defaults:`, configErr.message);
|
|
55
|
-
}
|
|
56
|
-
} else {
|
|
57
|
-
console.warn(`[RegistryClient] [QUEUE] queueConfig not available, using default options for ${queueName}`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return queueOptions;
|
|
61
|
-
}
|
|
62
24
|
|
|
63
25
|
class ServiceRegistryClient extends EventEmitter {
|
|
64
26
|
/**
|
|
@@ -95,6 +57,7 @@ class ServiceRegistryClient extends EventEmitter {
|
|
|
95
57
|
|
|
96
58
|
// Validation proof (injected via constructor - DEPENDENCY INJECTION)
|
|
97
59
|
this.validationProof = validationProof;
|
|
60
|
+
this._verifiedInfraQueues = new Set();
|
|
98
61
|
}
|
|
99
62
|
|
|
100
63
|
/**
|
|
@@ -118,8 +81,8 @@ class ServiceRegistryClient extends EventEmitter {
|
|
|
118
81
|
// Create service-specific registry event queue (for certificate delivery)
|
|
119
82
|
this.serviceRegistryQueue = `${this.serviceName}.registry`;
|
|
120
83
|
|
|
121
|
-
// Ensure existence of
|
|
122
|
-
await this.queueManager.ensureQueues([this.
|
|
84
|
+
// Ensure existence of service-specific queues only (infrastructure queues must already exist)
|
|
85
|
+
await this.queueManager.ensureQueues([this.serviceResponseQueue, this.serviceRegistryQueue]);
|
|
123
86
|
|
|
124
87
|
// CRITICAL: Before consume(), we must assertQueue with correct parameters
|
|
125
88
|
// amqplib's channel.consume() may internally call assertQueue() WITHOUT parameters
|
|
@@ -241,6 +204,49 @@ class ServiceRegistryClient extends EventEmitter {
|
|
|
241
204
|
}
|
|
242
205
|
}
|
|
243
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Ensure an infrastructure queue exists without mutating it.
|
|
209
|
+
* Uses a temporary channel so failures don't kill the primary channel.
|
|
210
|
+
* @param {string} queueName
|
|
211
|
+
* @returns {Promise<void>}
|
|
212
|
+
* @private
|
|
213
|
+
*/
|
|
214
|
+
async _ensureInfrastructureQueue(queueName) {
|
|
215
|
+
if (!queueName) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (!queueConfig?.isInfrastructureQueue(queueName)) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (this._verifiedInfraQueues.has(queueName)) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (!this.queueManager?.conn) {
|
|
228
|
+
console.warn(`[RegistryClient] ${this.serviceName}: MQ connection not ready, cannot verify infrastructure queue ${queueName}`);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const verificationChannel = await this.queueManager.conn.createChannel();
|
|
233
|
+
try {
|
|
234
|
+
await verificationChannel.checkQueue(queueName);
|
|
235
|
+
this._verifiedInfraQueues.add(queueName);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
if (error.code === 404) {
|
|
238
|
+
throw new Error(`[RegistryClient] Infrastructure queue '${queueName}' is missing. Ensure the responsible infrastructure service has initialized it.`);
|
|
239
|
+
}
|
|
240
|
+
throw error;
|
|
241
|
+
} finally {
|
|
242
|
+
try {
|
|
243
|
+
await verificationChannel.close();
|
|
244
|
+
} catch (closeErr) {
|
|
245
|
+
console.warn(`[RegistryClient] ${this.serviceName}: Failed to close verification channel for ${queueName}:`, closeErr.message);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
244
250
|
/**
|
|
245
251
|
* Registers the service with the registry.
|
|
246
252
|
* Registry will validate if the service is properly tested and valid.
|
|
@@ -317,36 +323,7 @@ class ServiceRegistryClient extends EventEmitter {
|
|
|
317
323
|
// CRITICAL: Use queueConfig.js to get correct parameters (TTL, max-length, etc.)
|
|
318
324
|
// This prevents 406 PRECONDITION-FAILED errors from TTL mismatches
|
|
319
325
|
console.log(`[RegistryClient] [PUBLISH] Preparing to publish to ${this.registryQueue}`);
|
|
320
|
-
|
|
321
|
-
let queueOptions = { durable: true };
|
|
322
|
-
try {
|
|
323
|
-
const queueConfig = require('@onlineapps/conn-infra-mq/src/config/queueConfig');
|
|
324
|
-
if (queueConfig.isInfrastructureQueue(this.registryQueue)) {
|
|
325
|
-
const infraConfig = queueConfig.getInfrastructureQueueConfig(this.registryQueue);
|
|
326
|
-
queueOptions = {
|
|
327
|
-
durable: infraConfig.durable !== false,
|
|
328
|
-
arguments: { ...infraConfig.arguments }
|
|
329
|
-
};
|
|
330
|
-
console.log(`[RegistryClient] [PUBLISH] Using infrastructure queue config for ${this.registryQueue}:`, JSON.stringify(queueOptions));
|
|
331
|
-
}
|
|
332
|
-
} catch (configErr) {
|
|
333
|
-
console.warn(`[RegistryClient] [PUBLISH] Failed to get config for ${this.registryQueue}, using defaults:`, configErr.message);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Use checkQueue to avoid 406 PRECONDITION-FAILED closing the channel
|
|
337
|
-
try {
|
|
338
|
-
await this.queueManager.channel.checkQueue(this.registryQueue);
|
|
339
|
-
console.log(`[RegistryClient] [PUBLISH] ✓ Queue ${this.registryQueue} exists`);
|
|
340
|
-
} catch (checkErr) {
|
|
341
|
-
if (checkErr.code === 404) {
|
|
342
|
-
console.log(`[RegistryClient] [PUBLISH] Queue ${this.registryQueue} does not exist (404), creating with options:`, JSON.stringify(queueOptions));
|
|
343
|
-
await this.queueManager.channel.assertQueue(this.registryQueue, queueOptions);
|
|
344
|
-
console.log(`[RegistryClient] [PUBLISH] ✓ Created queue ${this.registryQueue}`);
|
|
345
|
-
} else {
|
|
346
|
-
console.warn(`[RegistryClient] [PUBLISH] Queue ${this.registryQueue} exists with different arguments:`, checkErr.message);
|
|
347
|
-
// If 406 or other error, queue exists - proceed to publish
|
|
348
|
-
}
|
|
349
|
-
}
|
|
326
|
+
await this._ensureInfrastructureQueue(this.registryQueue);
|
|
350
327
|
console.log(`[RegistryClient] ${this.serviceName}: Sending registration message to queue: ${this.registryQueue}`);
|
|
351
328
|
console.log(`[RegistryClient] ${this.serviceName}: Message type: ${msg.type}, serviceName: ${msg.serviceName}, version: ${msg.version}`);
|
|
352
329
|
this.queueManager.channel.sendToQueue(
|
|
@@ -388,21 +365,7 @@ class ServiceRegistryClient extends EventEmitter {
|
|
|
388
365
|
// Send deregistration message to registry
|
|
389
366
|
// CRITICAL: Use queueConfig.js to get correct parameters (TTL, max-length, etc.)
|
|
390
367
|
console.log(`[RegistryClient] [PUBLISH] Preparing to publish to ${this.registryQueue} (deregister)`);
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
// Use checkQueue to avoid 406 PRECONDITION-FAILED closing the channel
|
|
394
|
-
try {
|
|
395
|
-
await this.queueManager.channel.checkQueue(this.registryQueue);
|
|
396
|
-
console.log(`[RegistryClient] [PUBLISH] ✓ Queue ${this.registryQueue} exists`);
|
|
397
|
-
} catch (checkErr) {
|
|
398
|
-
if (checkErr.code === 404) {
|
|
399
|
-
console.log(`[RegistryClient] [PUBLISH] Queue ${this.registryQueue} does not exist (404), creating with options:`, JSON.stringify(queueOptions));
|
|
400
|
-
await this.queueManager.channel.assertQueue(this.registryQueue, queueOptions);
|
|
401
|
-
console.log(`[RegistryClient] [PUBLISH] ✓ Created queue ${this.registryQueue}`);
|
|
402
|
-
} else {
|
|
403
|
-
console.warn(`[RegistryClient] [PUBLISH] Queue ${this.registryQueue} exists with different arguments:`, checkErr.message);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
368
|
+
await this._ensureInfrastructureQueue(this.registryQueue);
|
|
406
369
|
this.queueManager.channel.sendToQueue(
|
|
407
370
|
this.registryQueue,
|
|
408
371
|
Buffer.from(JSON.stringify(msg)),
|
|
@@ -447,21 +410,7 @@ class ServiceRegistryClient extends EventEmitter {
|
|
|
447
410
|
};
|
|
448
411
|
// CRITICAL: Use queueConfig.js to get correct parameters (TTL, max-length, etc.)
|
|
449
412
|
console.log(`[RegistryClient] [PUBLISH] Preparing to publish to ${this.registryQueue} (heartbeat)`);
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
// Use checkQueue to avoid 406 PRECONDITION-FAILED closing the channel
|
|
453
|
-
try {
|
|
454
|
-
await this.queueManager.channel.checkQueue(this.registryQueue);
|
|
455
|
-
console.log(`[RegistryClient] [PUBLISH] ✓ Queue ${this.registryQueue} exists`);
|
|
456
|
-
} catch (checkErr) {
|
|
457
|
-
if (checkErr.code === 404) {
|
|
458
|
-
console.log(`[RegistryClient] [PUBLISH] Queue ${this.registryQueue} does not exist (404), creating with options:`, JSON.stringify(queueOptions));
|
|
459
|
-
await this.queueManager.channel.assertQueue(this.registryQueue, queueOptions);
|
|
460
|
-
console.log(`[RegistryClient] [PUBLISH] ✓ Created queue ${this.registryQueue}`);
|
|
461
|
-
} else {
|
|
462
|
-
console.warn(`[RegistryClient] [PUBLISH] Queue ${this.registryQueue} exists with different arguments:`, checkErr.message);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
413
|
+
await this._ensureInfrastructureQueue(this.registryQueue);
|
|
465
414
|
this.queueManager.channel.sendToQueue(
|
|
466
415
|
this.registryQueue,
|
|
467
416
|
Buffer.from(JSON.stringify(msg)),
|
|
@@ -507,21 +456,7 @@ class ServiceRegistryClient extends EventEmitter {
|
|
|
507
456
|
};
|
|
508
457
|
// CRITICAL: Use queueConfig.js to get correct parameters (TTL, max-length, etc.)
|
|
509
458
|
console.log(`[RegistryClient] [PUBLISH] Preparing to publish to ${this.registryQueue} (apiDescription)`);
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
// Use checkQueue to avoid 406 PRECONDITION-FAILED closing the channel
|
|
513
|
-
try {
|
|
514
|
-
await this.queueManager.channel.checkQueue(this.registryQueue);
|
|
515
|
-
console.log(`[RegistryClient] [PUBLISH] ✓ Queue ${this.registryQueue} exists`);
|
|
516
|
-
} catch (checkErr) {
|
|
517
|
-
if (checkErr.code === 404) {
|
|
518
|
-
console.log(`[RegistryClient] [PUBLISH] Queue ${this.registryQueue} does not exist (404), creating with options:`, JSON.stringify(queueOptions));
|
|
519
|
-
await this.queueManager.channel.assertQueue(this.registryQueue, queueOptions);
|
|
520
|
-
console.log(`[RegistryClient] [PUBLISH] ✓ Created queue ${this.registryQueue}`);
|
|
521
|
-
} else {
|
|
522
|
-
console.warn(`[RegistryClient] [PUBLISH] Queue ${this.registryQueue} exists with different arguments:`, checkErr.message);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
459
|
+
await this._ensureInfrastructureQueue(this.registryQueue);
|
|
525
460
|
this.queueManager.channel.sendToQueue(
|
|
526
461
|
this.registryQueue,
|
|
527
462
|
Buffer.from(JSON.stringify(msg)),
|