@onlineapps/conn-orch-registry 1.1.5 → 1.1.6

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.5",
3
+ "version": "1.1.6",
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": [
@@ -19,6 +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 fs = require('fs');
23
+ const path = require('path');
22
24
 
23
25
  class ServiceRegistryClient extends EventEmitter {
24
26
  /**
@@ -32,7 +34,7 @@ class ServiceRegistryClient extends EventEmitter {
32
34
  * @param {string} [opts.registryQueue='registry_office'] - Queue name for registry messages
33
35
  */
34
36
  constructor({ amqpUrl, serviceName, version, specificationEndpoint = '/api/v1/specification',
35
- heartbeatInterval = 10000, apiQueue = 'api_services_queuer', registryQueue = 'registry_office',
37
+ heartbeatInterval = 10000, apiQueue = 'api_services_queuer', registryQueue = 'registry.register',
36
38
  redis = null, storageConfig = {} }) {
37
39
  super();
38
40
  if (!amqpUrl || !serviceName || !version) {
@@ -51,6 +53,9 @@ class ServiceRegistryClient extends EventEmitter {
51
53
  this.eventConsumer = null;
52
54
  this.redis = redis;
53
55
  this.storageConfig = storageConfig;
56
+
57
+ // Validation proof (loaded from .validation-proof.json)
58
+ this.validationProof = null;
54
59
  }
55
60
 
56
61
  /**
@@ -60,11 +65,17 @@ class ServiceRegistryClient extends EventEmitter {
60
65
  async init() {
61
66
  await this.queueManager.init();
62
67
 
68
+ // Load validation proof if exists
69
+ await this._loadValidationProof();
70
+
63
71
  // Create service-specific response queue
64
72
  this.serviceResponseQueue = `${this.serviceName}.responses`;
65
73
 
74
+ // Create service-specific registry event queue (for certificate delivery)
75
+ this.serviceRegistryQueue = `${this.serviceName}.registry`;
76
+
66
77
  // Ensure existence of API, registry and service response queues
67
- await this.queueManager.ensureQueues([this.apiQueue, this.registryQueue, this.serviceResponseQueue]);
78
+ await this.queueManager.ensureQueues([this.apiQueue, this.registryQueue, this.serviceResponseQueue, this.serviceRegistryQueue]);
68
79
 
69
80
  // Start consuming service response queue for registry responses
70
81
  await this.queueManager.channel.consume(
@@ -72,6 +83,41 @@ class ServiceRegistryClient extends EventEmitter {
72
83
  msg => this._handleRegistryMessage(msg),
73
84
  { noAck: false }
74
85
  );
86
+
87
+ // CRITICAL: Also listen on registry event queue for certificate delivery
88
+ await this.queueManager.channel.consume(
89
+ this.serviceRegistryQueue,
90
+ msg => this._handleRegistryMessage(msg),
91
+ { noAck: false }
92
+ );
93
+ }
94
+
95
+ /**
96
+ * Loads validation proof from .validation-proof.json in service root directory.
97
+ * Called during initialization.
98
+ * @private
99
+ * @returns {Promise<void>}
100
+ */
101
+ async _loadValidationProof() {
102
+ try {
103
+ // Look for .validation-proof.json in process.cwd() (service root)
104
+ const proofPath = path.join(process.cwd(), '.validation-proof.json');
105
+
106
+ if (fs.existsSync(proofPath)) {
107
+ const proofData = JSON.parse(fs.readFileSync(proofPath, 'utf8'));
108
+
109
+ if (proofData.validationProof && proofData.validationData) {
110
+ this.validationProof = {
111
+ hash: proofData.validationProof,
112
+ data: proofData.validationData
113
+ };
114
+ console.log(`[RegistryClient] Validation proof loaded: ${this.validationProof.hash.substring(0, 16)}...`);
115
+ }
116
+ }
117
+ } catch (error) {
118
+ // Non-critical error - service can still register without proof (will trigger Tier 2 validation)
119
+ console.warn(`[RegistryClient] Could not load validation proof: ${error.message}`);
120
+ }
75
121
  }
76
122
 
77
123
  /**
@@ -99,7 +145,8 @@ class ServiceRegistryClient extends EventEmitter {
99
145
  }
100
146
 
101
147
  // Handle registration response from registry
102
- if (payload.type === 'registerResponse' && payload.requestId) {
148
+ // Registry sends 'register.confirmed' after validation
149
+ if ((payload.type === 'registerResponse' || payload.type === 'register.confirmed') && payload.requestId) {
103
150
  if (this.pendingRegistrations && this.pendingRegistrations.has(payload.requestId)) {
104
151
  const { resolve } = this.pendingRegistrations.get(payload.requestId);
105
152
  this.pendingRegistrations.delete(payload.requestId);
@@ -111,7 +158,8 @@ class ServiceRegistryClient extends EventEmitter {
111
158
  serviceName: this.serviceName,
112
159
  version: this.version,
113
160
  registrationId: payload.registrationId,
114
- validated: payload.validated || false
161
+ validated: payload.validated || payload.success, // Consider successful registration as validated
162
+ certificate: payload.certificate || null // Include certificate from Registry
115
163
  });
116
164
  }
117
165
  }
@@ -155,6 +203,13 @@ class ServiceRegistryClient extends EventEmitter {
155
203
  timestamp: new Date().toISOString()
156
204
  };
157
205
 
206
+ // Include validation proof if loaded
207
+ if (this.validationProof) {
208
+ msg.validationProof = this.validationProof.hash;
209
+ msg.validationData = this.validationProof.data;
210
+ console.log(`[RegistryClient] Including validation proof in registration: ${this.validationProof.hash.substring(0, 16)}...`);
211
+ }
212
+
158
213
  // Create promise to wait for registration response
159
214
  const timeout = serviceInfo.timeout || 30000; // 30 seconds default
160
215
  const responsePromise = new Promise((resolve, reject) => {
@@ -234,6 +289,14 @@ class ServiceRegistryClient extends EventEmitter {
234
289
  };
235
290
  }
236
291
 
292
+ /**
293
+ * Alias for deregister() - used by ServiceWrapper.shutdown()
294
+ * @returns {Promise<Object>} Deregistration result
295
+ */
296
+ async unregister() {
297
+ return this.deregister();
298
+ }
299
+
237
300
  /**
238
301
  * Sends a heartbeat message to the API queue.
239
302
  * Should be called only after successful registration.