@onlineapps/service-wrapper 2.0.30 → 2.0.32
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 +1 -1
- package/src/ServiceWrapper.js +47 -38
package/package.json
CHANGED
package/src/ServiceWrapper.js
CHANGED
|
@@ -137,14 +137,16 @@ class ServiceWrapper {
|
|
|
137
137
|
* @async
|
|
138
138
|
*/
|
|
139
139
|
async initialize() {
|
|
140
|
-
|
|
141
|
-
console
|
|
140
|
+
if (this.isInitialized) {
|
|
141
|
+
// Logger might not be initialized yet, use console as fallback
|
|
142
|
+
(this.logger || console).warn('ServiceWrapper already initialized');
|
|
142
143
|
return;
|
|
143
144
|
}
|
|
144
145
|
|
|
145
146
|
try {
|
|
146
147
|
const serviceName = this.config.service?.name || 'unnamed-service';
|
|
147
|
-
console
|
|
148
|
+
// Logger might not be initialized yet, use console as fallback
|
|
149
|
+
(this.logger || console).info(`Initializing ServiceWrapper for ${serviceName}`);
|
|
148
150
|
|
|
149
151
|
// 1. Initialize monitoring first (needed for logging)
|
|
150
152
|
if (this.config.wrapper?.monitoring?.enabled !== false) {
|
|
@@ -190,10 +192,15 @@ class ServiceWrapper {
|
|
|
190
192
|
}
|
|
191
193
|
|
|
192
194
|
this.isInitialized = true;
|
|
193
|
-
|
|
195
|
+
this.logger?.info(`ServiceWrapper initialized successfully for ${serviceName}`);
|
|
194
196
|
|
|
195
197
|
} catch (error) {
|
|
196
|
-
|
|
198
|
+
// Always log errors - use logger if available, otherwise console
|
|
199
|
+
if (this.logger) {
|
|
200
|
+
this.logger.error('Failed to initialize ServiceWrapper', { error: error.message, stack: error.stack });
|
|
201
|
+
} else {
|
|
202
|
+
console.error('Failed to initialize ServiceWrapper:', error);
|
|
203
|
+
}
|
|
197
204
|
throw error;
|
|
198
205
|
}
|
|
199
206
|
}
|
|
@@ -205,14 +212,16 @@ class ServiceWrapper {
|
|
|
205
212
|
async _initializeMonitoring() {
|
|
206
213
|
const serviceName = this.config.service?.name || 'unnamed-service';
|
|
207
214
|
|
|
208
|
-
|
|
209
|
-
|
|
215
|
+
// Init returns API object with logger, info, error, warn, debug methods
|
|
216
|
+
this.monitoring = await MonitoringConnector.init({
|
|
210
217
|
serviceName,
|
|
211
218
|
...this.config.wrapper?.monitoring
|
|
212
219
|
});
|
|
213
220
|
|
|
221
|
+
// Logger is the API object returned from init (has logger, info, error, warn, debug)
|
|
214
222
|
this.logger = this.monitoring;
|
|
215
|
-
|
|
223
|
+
// Logger is now available, use it
|
|
224
|
+
this.logger.info('Monitoring connector initialized');
|
|
216
225
|
|
|
217
226
|
// Add monitoring middleware to Express app
|
|
218
227
|
if (this.app) {
|
|
@@ -257,7 +266,7 @@ class ServiceWrapper {
|
|
|
257
266
|
});
|
|
258
267
|
|
|
259
268
|
await this.mqClient.connect();
|
|
260
|
-
|
|
269
|
+
this.logger?.info('MQ connector initialized');
|
|
261
270
|
|
|
262
271
|
// NOTE: Business services (ServiceWrapper) do NOT create infrastructure queues
|
|
263
272
|
// Infrastructure queues are created by infrastructure services (Monitoring Consumer, Gateway)
|
|
@@ -290,7 +299,7 @@ class ServiceWrapper {
|
|
|
290
299
|
|
|
291
300
|
// Initialize registry client connection
|
|
292
301
|
await this.registryClient.init();
|
|
293
|
-
|
|
302
|
+
this.logger?.info('Registry client initialized');
|
|
294
303
|
|
|
295
304
|
// Register service
|
|
296
305
|
const serviceInfo = {
|
|
@@ -308,28 +317,28 @@ class ServiceWrapper {
|
|
|
308
317
|
|
|
309
318
|
try {
|
|
310
319
|
const registrationResult = await this.registryClient.register(serviceInfo);
|
|
311
|
-
|
|
320
|
+
this.logger?.info(`Service registered: ${serviceName}`, { registrationResult });
|
|
312
321
|
|
|
313
322
|
// Store certificate if received
|
|
314
323
|
if (registrationResult.certificate) {
|
|
315
324
|
this.certificate = registrationResult.certificate;
|
|
316
|
-
|
|
325
|
+
this.logger?.info(`✓ Certificate received: ${registrationResult.certificate.certificateId}`);
|
|
317
326
|
}
|
|
318
327
|
|
|
319
328
|
// CRITICAL: Start workflow listeners ONLY after successful validation and registration with certificate
|
|
320
329
|
// Both workflow.init and service-specific listeners start here
|
|
321
330
|
if (registrationResult.success && registrationResult.certificate) {
|
|
322
|
-
|
|
331
|
+
this.logger?.info('✓ Certificate validated, starting workflow listeners...');
|
|
323
332
|
// Start workflow.init listener (for all services)
|
|
324
333
|
await this._startWorkflowInitListener();
|
|
325
334
|
// Start service-specific workflow listener
|
|
326
335
|
await this._startServiceWorkflowListener();
|
|
327
336
|
} else {
|
|
328
|
-
|
|
337
|
+
this.logger?.warn('⚠ Registration succeeded but no certificate received - workflow listeners NOT started');
|
|
329
338
|
}
|
|
330
339
|
|
|
331
340
|
} catch (error) {
|
|
332
|
-
|
|
341
|
+
this.logger?.error(`Service registration failed: ${error.message}`, { error: error.message, stack: error.stack });
|
|
333
342
|
throw new Error(`Failed to register service ${serviceName}: ${error.message}`);
|
|
334
343
|
}
|
|
335
344
|
|
|
@@ -338,13 +347,13 @@ class ServiceWrapper {
|
|
|
338
347
|
const heartbeatInterval = parseInt(process.env.HEARTBEAT_INTERVAL) ||
|
|
339
348
|
this.config.wrapper?.registry?.heartbeatInterval ||
|
|
340
349
|
10000;
|
|
341
|
-
|
|
350
|
+
this.logger?.info(`[ServiceWrapper] Heartbeat interval set to ${heartbeatInterval}ms`);
|
|
342
351
|
|
|
343
352
|
this.heartbeatTimer = setInterval(async () => {
|
|
344
353
|
try {
|
|
345
354
|
await this.registryClient.sendHeartbeat(serviceName);
|
|
346
355
|
} catch (error) {
|
|
347
|
-
|
|
356
|
+
this.logger?.error('Heartbeat failed', { error: error.message, stack: error.stack });
|
|
348
357
|
}
|
|
349
358
|
}, heartbeatInterval);
|
|
350
359
|
}
|
|
@@ -356,7 +365,7 @@ class ServiceWrapper {
|
|
|
356
365
|
async _initializeCache() {
|
|
357
366
|
const cacheUrl = this.config.wrapper?.cache?.url;
|
|
358
367
|
if (!cacheUrl) {
|
|
359
|
-
|
|
368
|
+
this.logger?.warn('Cache enabled but no URL provided. Skipping cache initialization');
|
|
360
369
|
return;
|
|
361
370
|
}
|
|
362
371
|
|
|
@@ -369,7 +378,7 @@ class ServiceWrapper {
|
|
|
369
378
|
});
|
|
370
379
|
|
|
371
380
|
await this.cacheConnector.connect();
|
|
372
|
-
|
|
381
|
+
this.logger?.info('Cache connector initialized');
|
|
373
382
|
}
|
|
374
383
|
|
|
375
384
|
/**
|
|
@@ -404,7 +413,7 @@ class ServiceWrapper {
|
|
|
404
413
|
res.json(health);
|
|
405
414
|
});
|
|
406
415
|
|
|
407
|
-
|
|
416
|
+
this.logger?.info(`Health check endpoint registered at ${healthEndpoint}`);
|
|
408
417
|
}
|
|
409
418
|
|
|
410
419
|
/**
|
|
@@ -455,7 +464,7 @@ class ServiceWrapper {
|
|
|
455
464
|
defaultTimeout: this.config.wrapper?.timeout || 30000
|
|
456
465
|
});
|
|
457
466
|
|
|
458
|
-
|
|
467
|
+
this.logger?.info('Orchestrator initialized');
|
|
459
468
|
}
|
|
460
469
|
|
|
461
470
|
/**
|
|
@@ -465,7 +474,7 @@ class ServiceWrapper {
|
|
|
465
474
|
*/
|
|
466
475
|
async _startWorkflowInitListener() {
|
|
467
476
|
if (!this.mqClient) {
|
|
468
|
-
|
|
477
|
+
this.logger?.warn('Cannot start workflow.init listener: MQ client not initialized');
|
|
469
478
|
return;
|
|
470
479
|
}
|
|
471
480
|
|
|
@@ -474,7 +483,7 @@ class ServiceWrapper {
|
|
|
474
483
|
await this._processWorkflowMessage(message, 'workflow.init');
|
|
475
484
|
});
|
|
476
485
|
|
|
477
|
-
|
|
486
|
+
this.logger?.info('✓ workflow.init listener started (after successful registration)');
|
|
478
487
|
}
|
|
479
488
|
|
|
480
489
|
/**
|
|
@@ -483,7 +492,7 @@ class ServiceWrapper {
|
|
|
483
492
|
*/
|
|
484
493
|
async _startServiceWorkflowListener() {
|
|
485
494
|
if (!this.mqClient) {
|
|
486
|
-
|
|
495
|
+
this.logger?.warn('Cannot start service workflow listener: MQ client not initialized');
|
|
487
496
|
return;
|
|
488
497
|
}
|
|
489
498
|
|
|
@@ -495,7 +504,7 @@ class ServiceWrapper {
|
|
|
495
504
|
await this._processWorkflowMessage(message, serviceQueue);
|
|
496
505
|
});
|
|
497
506
|
|
|
498
|
-
|
|
507
|
+
this.logger?.info(`✓ Service-specific workflow listener started: ${serviceQueue}`);
|
|
499
508
|
}
|
|
500
509
|
|
|
501
510
|
/**
|
|
@@ -520,7 +529,7 @@ class ServiceWrapper {
|
|
|
520
529
|
const isTest = flags.includes('test');
|
|
521
530
|
const isTier2Validation = flags.includes('tier2-validation');
|
|
522
531
|
|
|
523
|
-
|
|
532
|
+
this.logger?.debug(`Processing message from ${queueName}`, {
|
|
524
533
|
workflow_id: message.workflow_id,
|
|
525
534
|
step: message.step?.operation || message.operation,
|
|
526
535
|
flags,
|
|
@@ -530,7 +539,7 @@ class ServiceWrapper {
|
|
|
530
539
|
// Check if this message is for our service
|
|
531
540
|
const serviceName = this.config.service?.name || 'unnamed-service';
|
|
532
541
|
if (message.step?.service && message.step.service !== serviceName) {
|
|
533
|
-
|
|
542
|
+
this.logger?.debug(`Message not for this service (target: ${message.step.service})`);
|
|
534
543
|
return;
|
|
535
544
|
}
|
|
536
545
|
|
|
@@ -635,7 +644,7 @@ class ServiceWrapper {
|
|
|
635
644
|
const url = `http://localhost:${servicePort}${operation.endpoint}`;
|
|
636
645
|
const method = operation.method || 'POST';
|
|
637
646
|
|
|
638
|
-
|
|
647
|
+
this.logger?.debug(`Executing operation ${operationName} via ${method} ${url}`);
|
|
639
648
|
|
|
640
649
|
// Make HTTP request using fetch (Node.js 18+) or http module
|
|
641
650
|
const http = require('http');
|
|
@@ -690,7 +699,7 @@ class ServiceWrapper {
|
|
|
690
699
|
*/
|
|
691
700
|
async shutdown() {
|
|
692
701
|
const serviceName = this.config.service?.name || 'unnamed-service';
|
|
693
|
-
|
|
702
|
+
this.logger?.info(`Shutting down ServiceWrapper for ${serviceName}`);
|
|
694
703
|
|
|
695
704
|
try {
|
|
696
705
|
// Stop heartbeat
|
|
@@ -714,10 +723,10 @@ class ServiceWrapper {
|
|
|
714
723
|
}
|
|
715
724
|
|
|
716
725
|
this.isInitialized = false;
|
|
717
|
-
|
|
726
|
+
this.logger?.info('ServiceWrapper shutdown complete');
|
|
718
727
|
|
|
719
728
|
} catch (error) {
|
|
720
|
-
|
|
729
|
+
this.logger?.error('Error during shutdown', { error: error.message, stack: error.stack });
|
|
721
730
|
throw error;
|
|
722
731
|
}
|
|
723
732
|
}
|
|
@@ -735,7 +744,7 @@ class ServiceWrapper {
|
|
|
735
744
|
const proofPath = path.join(process.cwd(), '.validation-proof.json');
|
|
736
745
|
|
|
737
746
|
if (!fs.existsSync(proofPath)) {
|
|
738
|
-
|
|
747
|
+
this.logger?.warn('Validation proof not found', { proofPath });
|
|
739
748
|
return null;
|
|
740
749
|
}
|
|
741
750
|
|
|
@@ -744,15 +753,15 @@ class ServiceWrapper {
|
|
|
744
753
|
|
|
745
754
|
// Basic validation
|
|
746
755
|
if (!proof.validationProof || !proof.validationData) {
|
|
747
|
-
|
|
756
|
+
this.logger?.warn('Invalid validation proof format');
|
|
748
757
|
return null;
|
|
749
758
|
}
|
|
750
759
|
|
|
751
|
-
|
|
760
|
+
this.logger?.info('✓ Validation proof loaded', { proofHash: proof.validationProof.substring(0, 16) + '...' });
|
|
752
761
|
return proof;
|
|
753
762
|
|
|
754
763
|
} catch (error) {
|
|
755
|
-
|
|
764
|
+
this.logger?.warn('Failed to load validation proof', { error: error.message, stack: error.stack });
|
|
756
765
|
return null;
|
|
757
766
|
}
|
|
758
767
|
}
|
|
@@ -783,7 +792,7 @@ class ServiceWrapper {
|
|
|
783
792
|
// Build service URL for validation (HTTP calls to running server)
|
|
784
793
|
const serviceUrl = `http://localhost:${servicePort}`;
|
|
785
794
|
|
|
786
|
-
|
|
795
|
+
this.logger?.info('[ServiceWrapper] Checking validation proof...');
|
|
787
796
|
|
|
788
797
|
// Use injected orchestrator (for testing) or create new one (production)
|
|
789
798
|
const orchestrator = this._injectedValidationOrchestrator || new ValidationOrchestrator({
|
|
@@ -801,9 +810,9 @@ class ServiceWrapper {
|
|
|
801
810
|
}
|
|
802
811
|
|
|
803
812
|
if (result.skipped) {
|
|
804
|
-
|
|
813
|
+
this.logger?.info('[ServiceWrapper] ✓ Using existing validation proof');
|
|
805
814
|
} else {
|
|
806
|
-
|
|
815
|
+
this.logger?.info('[ServiceWrapper] ✓ Validation completed successfully');
|
|
807
816
|
}
|
|
808
817
|
|
|
809
818
|
// Store proof for registration
|