@onlineapps/conn-orch-validator 2.0.0 → 2.0.2
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/ValidationOrchestrator.js +36 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlineapps/conn-orch-validator",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Validation orchestrator for OA Drive microservices - coordinates validation across all layers (base, infra, orch, business)",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -20,8 +20,14 @@ class ValidationOrchestrator {
|
|
|
20
20
|
this.serviceRoot = options.serviceRoot;
|
|
21
21
|
this.serviceName = options.serviceName;
|
|
22
22
|
this.serviceVersion = options.serviceVersion;
|
|
23
|
+
this.serviceUrl = options.serviceUrl; // NEW: Service URL for HTTP calls
|
|
23
24
|
this.logger = options.logger || console;
|
|
24
25
|
|
|
26
|
+
// Validate required options
|
|
27
|
+
if (!this.serviceUrl) {
|
|
28
|
+
throw new Error('serviceUrl is required for ValidationOrchestrator');
|
|
29
|
+
}
|
|
30
|
+
|
|
25
31
|
// Paths
|
|
26
32
|
this.configPath = path.join(this.serviceRoot, 'conn-config');
|
|
27
33
|
this.runtimePath = path.join(this.serviceRoot, 'conn-runtime');
|
|
@@ -32,7 +38,8 @@ class ValidationOrchestrator {
|
|
|
32
38
|
this.readinessValidator = new ServiceReadinessValidator();
|
|
33
39
|
this.cookbookRunner = new CookbookTestRunner({
|
|
34
40
|
servicePath: this.serviceRoot,
|
|
35
|
-
serviceName: this.serviceName
|
|
41
|
+
serviceName: this.serviceName,
|
|
42
|
+
serviceUrl: this.serviceUrl // Pass serviceUrl to CookbookTestRunner
|
|
36
43
|
});
|
|
37
44
|
}
|
|
38
45
|
|
|
@@ -41,12 +48,12 @@ class ValidationOrchestrator {
|
|
|
41
48
|
* Checks if proof exists and is valid, or runs full validation
|
|
42
49
|
*/
|
|
43
50
|
async validate() {
|
|
44
|
-
|
|
51
|
+
console.log('[ValidationOrchestrator] Starting validation...');
|
|
45
52
|
|
|
46
53
|
// Check if proof exists and is valid
|
|
47
54
|
const existingProof = await this.loadExistingProof();
|
|
48
55
|
if (existingProof && await this.isProofValid(existingProof)) {
|
|
49
|
-
|
|
56
|
+
console.log('[ValidationOrchestrator] ✓ Valid proof found, skipping validation');
|
|
50
57
|
return {
|
|
51
58
|
success: true,
|
|
52
59
|
proofExists: true,
|
|
@@ -56,7 +63,7 @@ class ValidationOrchestrator {
|
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
// Run full validation
|
|
59
|
-
|
|
66
|
+
console.log('[ValidationOrchestrator] No valid proof, running validation...');
|
|
60
67
|
return await this.runFullValidation();
|
|
61
68
|
}
|
|
62
69
|
|
|
@@ -74,7 +81,7 @@ class ValidationOrchestrator {
|
|
|
74
81
|
|
|
75
82
|
return proof;
|
|
76
83
|
} catch (error) {
|
|
77
|
-
|
|
84
|
+
console.warn(`[ValidationOrchestrator] Failed to load proof: ${error.message}`);
|
|
78
85
|
return null;
|
|
79
86
|
}
|
|
80
87
|
}
|
|
@@ -90,7 +97,7 @@ class ValidationOrchestrator {
|
|
|
90
97
|
|
|
91
98
|
// Check if fingerprint matches
|
|
92
99
|
if (proof.fingerprint !== currentFingerprint) {
|
|
93
|
-
|
|
100
|
+
console.log('[ValidationOrchestrator] Fingerprint mismatch (service changed)');
|
|
94
101
|
return false;
|
|
95
102
|
}
|
|
96
103
|
|
|
@@ -100,20 +107,20 @@ class ValidationOrchestrator {
|
|
|
100
107
|
const daysSinceValidation = (now - proofDate) / (1000 * 60 * 60 * 24);
|
|
101
108
|
|
|
102
109
|
if (daysSinceValidation > 30) {
|
|
103
|
-
|
|
110
|
+
console.log('[ValidationOrchestrator] Proof expired (>30 days old)');
|
|
104
111
|
return false;
|
|
105
112
|
}
|
|
106
113
|
|
|
107
114
|
// Verify proof signature
|
|
108
115
|
const isValid = ValidationProofCodec.verify(proof);
|
|
109
116
|
if (!isValid) {
|
|
110
|
-
|
|
117
|
+
console.warn('[ValidationOrchestrator] Proof signature invalid');
|
|
111
118
|
return false;
|
|
112
119
|
}
|
|
113
120
|
|
|
114
121
|
return true;
|
|
115
122
|
} catch (error) {
|
|
116
|
-
|
|
123
|
+
console.error(`[ValidationOrchestrator] Proof validation error: ${error.message}`);
|
|
117
124
|
return false;
|
|
118
125
|
}
|
|
119
126
|
}
|
|
@@ -170,7 +177,7 @@ class ValidationOrchestrator {
|
|
|
170
177
|
|
|
171
178
|
try {
|
|
172
179
|
// Step 1: Service Structure
|
|
173
|
-
|
|
180
|
+
console.log('[ValidationOrchestrator] Step 1/6: Service Structure');
|
|
174
181
|
results.steps.structure = await this.validateStructure();
|
|
175
182
|
if (!results.steps.structure.valid) {
|
|
176
183
|
results.success = false;
|
|
@@ -180,7 +187,7 @@ class ValidationOrchestrator {
|
|
|
180
187
|
}
|
|
181
188
|
|
|
182
189
|
// Step 2: Config Files
|
|
183
|
-
|
|
190
|
+
console.log('[ValidationOrchestrator] Step 2/6: Config Files');
|
|
184
191
|
results.steps.config = await this.validateConfig();
|
|
185
192
|
if (!results.steps.config.valid) {
|
|
186
193
|
results.success = false;
|
|
@@ -188,7 +195,7 @@ class ValidationOrchestrator {
|
|
|
188
195
|
}
|
|
189
196
|
|
|
190
197
|
// Step 3: Operations Compliance
|
|
191
|
-
|
|
198
|
+
console.log('[ValidationOrchestrator] Step 3/6: Operations Compliance');
|
|
192
199
|
results.steps.operations = await this.validateOperations();
|
|
193
200
|
if (!results.steps.operations.valid) {
|
|
194
201
|
results.success = false;
|
|
@@ -196,7 +203,7 @@ class ValidationOrchestrator {
|
|
|
196
203
|
}
|
|
197
204
|
|
|
198
205
|
// Step 4: Cookbook Tests
|
|
199
|
-
|
|
206
|
+
console.log('[ValidationOrchestrator] Step 4/6: Cookbook Tests');
|
|
200
207
|
results.steps.cookbooks = await this.runCookbookTests();
|
|
201
208
|
results.totalTests += results.steps.cookbooks.total || 0;
|
|
202
209
|
results.passedTests += results.steps.cookbooks.passed || 0;
|
|
@@ -207,7 +214,7 @@ class ValidationOrchestrator {
|
|
|
207
214
|
}
|
|
208
215
|
|
|
209
216
|
// Step 5: Service Readiness
|
|
210
|
-
|
|
217
|
+
console.log('[ValidationOrchestrator] Step 5/6: Service Readiness');
|
|
211
218
|
results.steps.readiness = await this.validateReadiness();
|
|
212
219
|
if (!results.steps.readiness.valid) {
|
|
213
220
|
results.success = false;
|
|
@@ -215,7 +222,7 @@ class ValidationOrchestrator {
|
|
|
215
222
|
}
|
|
216
223
|
|
|
217
224
|
// Step 6: Connector Integration
|
|
218
|
-
|
|
225
|
+
console.log('[ValidationOrchestrator] Step 6/6: Connector Integration');
|
|
219
226
|
results.steps.connectors = this.validateConnectors();
|
|
220
227
|
if (!results.steps.connectors.valid) {
|
|
221
228
|
// Non-critical - just warnings
|
|
@@ -226,7 +233,7 @@ class ValidationOrchestrator {
|
|
|
226
233
|
return await this.finalizeResults(results, startTime);
|
|
227
234
|
|
|
228
235
|
} catch (error) {
|
|
229
|
-
|
|
236
|
+
console.error(`[ValidationOrchestrator] Validation failed: ${error.message}`);
|
|
230
237
|
results.success = false;
|
|
231
238
|
results.errors.push(`Validation error: ${error.message}`);
|
|
232
239
|
return this.finalizeResults(results, startTime);
|
|
@@ -240,7 +247,7 @@ class ValidationOrchestrator {
|
|
|
240
247
|
try {
|
|
241
248
|
const result = this.structureValidator.validate();
|
|
242
249
|
|
|
243
|
-
|
|
250
|
+
console.log(`[ValidationOrchestrator] ✓ Service structure: ${result.valid ? 'PASS' : 'FAIL'}`);
|
|
244
251
|
return result;
|
|
245
252
|
} catch (error) {
|
|
246
253
|
return {
|
|
@@ -278,7 +285,7 @@ class ValidationOrchestrator {
|
|
|
278
285
|
}
|
|
279
286
|
}
|
|
280
287
|
|
|
281
|
-
|
|
288
|
+
console.log(`[ValidationOrchestrator] ✓ Config files: ${errors.length === 0 ? 'PASS' : 'FAIL'}`);
|
|
282
289
|
return {
|
|
283
290
|
valid: errors.length === 0,
|
|
284
291
|
errors: errors
|
|
@@ -322,7 +329,7 @@ class ValidationOrchestrator {
|
|
|
322
329
|
}
|
|
323
330
|
}
|
|
324
331
|
|
|
325
|
-
|
|
332
|
+
console.log(`[ValidationOrchestrator] ✓ Operations compliance: ${errors.length === 0 ? 'PASS' : 'FAIL'}`);
|
|
326
333
|
return {
|
|
327
334
|
valid: errors.length === 0,
|
|
328
335
|
errors: errors
|
|
@@ -343,7 +350,7 @@ class ValidationOrchestrator {
|
|
|
343
350
|
const cookbooksPath = path.join(this.serviceRoot, 'tests', 'cookbooks');
|
|
344
351
|
|
|
345
352
|
if (!fs.existsSync(cookbooksPath)) {
|
|
346
|
-
|
|
353
|
+
console.warn('[ValidationOrchestrator] No cookbook tests found (tests/cookbooks/ missing)');
|
|
347
354
|
return {
|
|
348
355
|
success: true,
|
|
349
356
|
total: 0,
|
|
@@ -355,7 +362,7 @@ class ValidationOrchestrator {
|
|
|
355
362
|
|
|
356
363
|
const result = await this.cookbookRunner.runCookbooks(cookbooksPath);
|
|
357
364
|
|
|
358
|
-
|
|
365
|
+
console.log(`[ValidationOrchestrator] ✓ Cookbook tests: ${result.passed}/${result.total} passed`);
|
|
359
366
|
return {
|
|
360
367
|
success: result.failed === 0,
|
|
361
368
|
total: result.total,
|
|
@@ -389,7 +396,7 @@ class ValidationOrchestrator {
|
|
|
389
396
|
operations: operations.operations
|
|
390
397
|
});
|
|
391
398
|
|
|
392
|
-
|
|
399
|
+
console.log(`[ValidationOrchestrator] ✓ Service readiness: ${result.ready ? 'PASS' : 'FAIL'}`);
|
|
393
400
|
return {
|
|
394
401
|
valid: result.ready,
|
|
395
402
|
errors: result.ready ? [] : result.errors || ['Service not ready']
|
|
@@ -410,7 +417,7 @@ class ValidationOrchestrator {
|
|
|
410
417
|
// This is validated implicitly through cookbook tests
|
|
411
418
|
// which test ServiceWrapper + all connectors
|
|
412
419
|
|
|
413
|
-
|
|
420
|
+
console.log('[ValidationOrchestrator] ✓ Connector integration: PASS (via cookbook tests)');
|
|
414
421
|
return {
|
|
415
422
|
valid: true,
|
|
416
423
|
warnings: []
|
|
@@ -464,16 +471,16 @@ class ValidationOrchestrator {
|
|
|
464
471
|
results.proof = encodedProof;
|
|
465
472
|
results.fingerprint = fingerprint;
|
|
466
473
|
|
|
467
|
-
|
|
468
|
-
|
|
474
|
+
console.log(`[ValidationOrchestrator] ✅ Validation PASSED (${duration}ms)`);
|
|
475
|
+
console.log(`[ValidationOrchestrator] Proof saved to: ${this.proofPath}`);
|
|
469
476
|
} catch (error) {
|
|
470
|
-
|
|
477
|
+
console.error(`[ValidationOrchestrator] Failed to generate proof: ${error.message}`);
|
|
471
478
|
results.success = false;
|
|
472
479
|
results.errors.push(`Proof generation failed: ${error.message}`);
|
|
473
480
|
}
|
|
474
481
|
} else {
|
|
475
|
-
|
|
476
|
-
|
|
482
|
+
console.error(`[ValidationOrchestrator] ❌ Validation FAILED (${duration}ms)`);
|
|
483
|
+
console.error(`[ValidationOrchestrator] Errors: ${results.errors.join(', ')}`);
|
|
477
484
|
}
|
|
478
485
|
|
|
479
486
|
return results;
|
|
@@ -496,7 +503,7 @@ class ValidationOrchestrator {
|
|
|
496
503
|
// Save proof
|
|
497
504
|
fs.writeFileSync(this.proofPath, JSON.stringify(proof, null, 2));
|
|
498
505
|
|
|
499
|
-
|
|
506
|
+
console.log(`[ValidationOrchestrator] Proof saved: ${this.proofPath}`);
|
|
500
507
|
} catch (error) {
|
|
501
508
|
throw new Error(`Failed to save proof: ${error.message}`);
|
|
502
509
|
}
|