@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/conn-orch-registry",
3
- "version": "1.1.22",
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",
@@ -19,15 +19,7 @@
19
19
  */
20
20
 
21
21
  const amqp = require('amqplib');
22
- // CRITICAL: Import queueConfig to ensure consistent queue parameters
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
- // Use checkQueue first to avoid 406 PRECONDITION-FAILED closing the channel
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 checkStartTime = Date.now();
108
- await this.channel.checkQueue(q);
109
- const checkEndTime = Date.now();
110
- console.log(`[QueueManager] [REGISTRY] [QUEUE] ✓ Queue ${q} exists (checkQueue took ${checkEndTime - checkStartTime}ms)`);
111
- // Queue exists - continue
112
- } catch (checkErr) {
113
- // If queue doesn't exist (404), create it with correct options from queueConfig
114
- if (checkErr.code === 404) {
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
  }
@@ -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 API, registry and service response queues
122
- await this.queueManager.ensureQueues([this.apiQueue, this.registryQueue, this.serviceResponseQueue, this.serviceRegistryQueue]);
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
- const queueOptions = getQueueOptions(this.registryQueue);
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
- const queueOptions = getQueueOptions(this.registryQueue);
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
- const queueOptions = getQueueOptions(this.registryQueue);
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)),