@onlineapps/conn-orch-validator 2.0.33 → 2.0.34

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/docs/DESIGN.md CHANGED
@@ -1,134 +1,80 @@
1
- # Connector-Testing Design Document
1
+ # conn-orch-validator Design
2
2
 
3
3
  ## Purpose
4
4
 
5
- The conn-orch-validator package provides a unified testing and validation framework for OA Drive microservices. It serves three critical functions:
5
+ Validation framework for OA Drive microservices. Drives two flows:
6
6
 
7
- 1. **Development Testing** - Mock infrastructure for isolated service testing
8
- 2. **Production Validation** - On-the-fly validation of new services during registration
9
- 3. **Service Readiness** - Complete verification before deployment
7
+ 1. **Pre-validation** (Tier 1) runs during `service-wrapper` startup. Verifies
8
+ structure (config files, package.json), readiness (endpoints respond, health
9
+ works) and produces a signed `validation-proof.json` stored under
10
+ `conn-runtime/`.
11
+ 2. **Readiness checks** — reusable probes (`createServiceReadinessTests`,
12
+ `createPreValidationTests`) consumable from unit/component test suites
13
+ of individual biz services.
10
14
 
11
- ## Key Principles
15
+ The single source of truth for service endpoint metadata is
16
+ [`operations.json`](../../../docs/standards/operations-registry-contract.md).
17
+ OpenAPI iteration (`paths`/`operationId`) is NOT supported — that legacy
18
+ surface was removed together with the now-retired `ServiceValidator` /
19
+ `TestOrchestrator` / `ServiceTestHarness` classes.
12
20
 
13
- ### No Duplication
14
- - Does NOT duplicate tests from individual connectors
15
- - Uses existing connector functionality where available
16
- - Focuses on integration and orchestration
21
+ ## Key Principles
17
22
 
18
- ### Production-Ready
19
- - Same code used in development AND production
20
- - Validates services before they join the ecosystem
21
- - Ensures cookbook compatibility
23
+ - **No duplication** — does not re-test individual connector logic; focuses on
24
+ integration, readiness and proof generation.
25
+ - **Production-ready** the exact same code runs locally, in CI and during
26
+ wrapper startup.
27
+ - **Fail-fast** — missing logger, missing serviceUrl, missing operations.json:
28
+ immediate throw.
22
29
 
23
30
  ## Components
24
31
 
25
- ### 1. Mock Infrastructure (Development)
26
- - `MockMQClient` - In-memory message queue simulation
27
- - `MockRegistry` - Service registry simulation
28
- - `MockStorage` - Object storage simulation
32
+ ### Mock Infrastructure (for unit tests)
33
+
34
+ - `MockMQClient` — in-memory message queue simulation
35
+ - `MockRegistry` service registry simulation
36
+ - `MockStorage` — object storage simulation
29
37
 
30
- ### 2. Validation Tools (Production)
31
- - `ServiceValidator` - OpenAPI compliance and endpoint testing
32
- - `WorkflowTestRunner` - Cookbook execution testing
33
- - `CookbookTestUtils` - Cookbook structure validation
38
+ ### Production Validation
34
39
 
35
- ### 3. Integration Framework
36
- - `ServiceTestHarness` - Complete test environment orchestration
40
+ - `ValidationOrchestrator` 6-step pre-validation pipeline, emits proof
41
+ - `ServiceReadinessValidator` — score-based readiness checks (operations /
42
+ endpoints / health / cookbook / registry)
43
+ - `ServiceStructureValidator` — config layout checks (config/service/*)
44
+ - `ValidationProofGenerator` — fingerprint + codec helpers
45
+ - `CookbookTestRunner` / `WorkflowTestRunner` — cookbook execution probes
46
+ - `CookbookTestUtils` — static cookbook-structure validators
37
47
 
38
- ## Use Cases
48
+ ### Test Suite Helpers
39
49
 
40
- ### Development Workflow
41
- ```javascript
42
- // Developer testing their service
43
- const harness = new ServiceTestHarness({
44
- service: myExpressApp,
45
- serviceName: 'my-service',
46
- openApiSpec: spec,
47
- mockInfrastructure: true // Use mocks
48
- });
50
+ - `createServiceReadinessTests(options)` — Jest suite generator
51
+ - `createPreValidationTests(options)` — Jest suite generator
49
52
 
50
- await harness.start();
51
- // Run tests...
52
- await harness.stop();
53
- ```
53
+ ## Integration Points
54
54
 
55
- ### Production Validation
56
- ```javascript
57
- // Registry validating new service
58
- const validator = new ServiceValidator();
59
- const result = await validator.validateService(
60
- serviceUrl,
61
- openApiSpec
62
- );
63
-
64
- if (!result.valid) {
65
- // Reject registration
66
- }
67
- ```
68
-
69
- ### Service-Wrapper Integration
70
- ```javascript
71
- // Service-wrapper using connector-testing
72
- class ServiceWrapper {
73
- async validateBeforeStart() {
74
- const validator = new ServiceValidator();
75
- const validation = await validator.validateService(
76
- `http://localhost:${this.port}`,
77
- this.openApiSpec
78
- );
79
-
80
- if (!validation.valid) {
81
- throw new Error('Service validation failed');
82
- }
83
- }
84
- }
85
- ```
86
-
87
- ## Testing Strategy
88
-
89
- ### What We Test
90
- 1. **Service Contract** - OpenAPI compliance
91
- 2. **Workflow Capability** - Can process cookbooks
92
- 3. **Infrastructure Integration** - Registry, MQ, Storage connectivity
93
- 4. **Health & Status** - Monitoring endpoints
94
-
95
- ### What We DON'T Test
96
- 1. Individual connector functionality (tested in connector packages)
97
- 2. Business logic correctness (service's responsibility)
98
- 3. Performance metrics (separate concern)
99
-
100
- ## Production Validation Flow
101
-
102
- ```
103
- New Service Registration
104
-
105
- [Registry]
106
-
107
- Uses connector-testing
108
-
109
- 1. Validate OpenAPI
110
- 2. Test all endpoints
111
- 3. Execute test cookbook
112
- 4. Verify health check
113
-
114
- Pass? → Accept : Reject
115
- ```
116
-
117
- ## Integration with Existing System
118
-
119
- ### Uses Existing Connectors
120
- - Leverages real connector implementations where possible
121
- - Only mocks what's necessary for isolation
122
- - Validates against actual connector interfaces
123
-
124
- ### Complements Existing Tests
125
- - Individual connectors have unit tests
126
- - Services have business logic tests
127
- - Connector-testing provides integration validation
128
-
129
- ## Future Enhancements
130
-
131
- 1. **Performance Benchmarking** - Baseline performance requirements
132
- 2. **Security Validation** - Authentication/authorization checks
133
- 3. **Chaos Testing** - Fault injection and recovery
134
- 4. **Compliance Checking** - Regulatory requirement validation
55
+ - `@onlineapps/service-wrapper` instantiates `ValidationOrchestrator` during
56
+ wrapper startup. Proof is cached under `conn-runtime/validation-proof.json`
57
+ (30-day validity, invalidated by config fingerprint change — includes
58
+ operations map, see
59
+ [operations-registry-contract.md §3](../../../docs/standards/operations-registry-contract.md)).
60
+ - Biz-service templates import `createPreValidationTests` /
61
+ `createServiceReadinessTests` from this package for their own test suites.
62
+
63
+ ## What We Test
64
+
65
+ 1. **Service contract** — operations.json structure + endpoint reachability
66
+ 2. **Workflow capability** — can process cookbooks
67
+ 3. **Infrastructure** — registry / MQ / storage connectivity
68
+ 4. **Health** — `/health` returns 200
69
+
70
+ ## What We DO NOT Test
71
+
72
+ 1. Individual connector behavior (tested in connector packages)
73
+ 2. Business logic correctness (service responsibility)
74
+ 3. Performance / load (separate concern)
75
+
76
+ ## Related Documentation
77
+
78
+ - [operations-registry-contract.md](../../../docs/standards/operations-registry-contract.md) — operations.json schema
79
+ - [validation-probe-contract.md](../../../docs/standards/validation-probe-contract.md) — required `example`/`default` fields for probes
80
+ - [validator.md](../../../docs/architecture/validator.md) — architecture overview
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/conn-orch-validator",
3
- "version": "2.0.33",
3
+ "version": "2.0.34",
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": {
@@ -21,7 +21,7 @@
21
21
  "author": "OnlineApps",
22
22
  "license": "PROPRIETARY",
23
23
  "dependencies": {
24
- "@onlineapps/service-validator-core": "1.0.12",
24
+ "@onlineapps/service-validator-core": "1.0.13",
25
25
  "@onlineapps/runtime-config": "1.0.2",
26
26
  "ajv": "^8.12.0",
27
27
  "ajv-formats": "^2.1.1",
@@ -1,21 +1,24 @@
1
1
  'use strict';
2
2
 
3
- const ServiceValidator = require('./ServiceValidator');
4
3
  const CookbookTestUtils = require('./CookbookTestUtils');
5
4
  const { resolveHeaders } = require('./utils/resolveHeaders');
6
5
 
7
6
  /**
8
- * ServiceReadinessValidator - Orchestrates complete service validation
9
- * Used by service-wrapper to verify service is ready for production
7
+ * ServiceReadinessValidator - Orchestrates complete service validation.
10
8
  *
11
- * IMPORTANT: Only supports operations.json format. OpenAPI is deprecated.
9
+ * Used by service-wrapper to verify a service is ready for production.
10
+ * Works exclusively against the operations.json contract — OpenAPI-style
11
+ * `paths` iteration was removed when the contract became the single source
12
+ * of truth for endpoint metadata.
13
+ *
14
+ * @see /api/docs/standards/operations-registry-contract.md §3
15
+ * @see /api/docs/standards/validation-probe-contract.md
12
16
  */
13
17
  class ServiceReadinessValidator {
14
18
  constructor(options = {}) {
15
19
  if (!options.logger || typeof options.logger.warn !== 'function') {
16
20
  throw new Error('[ServiceReadinessValidator] Logger is required — Expected object with warn() method');
17
21
  }
18
- this.validator = new ServiceValidator(options);
19
22
  this.logger = options.logger;
20
23
 
21
24
  // Readiness checks: core (80 points) + optional (20 points) = 100 points max
package/src/config.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Runtime configuration schema for @onlineapps/conn-orch-validator.
5
5
  *
6
6
  * Uses @onlineapps/runtime-config for unified priority:
7
- * 1. Explicit config (passed to TestOrchestrator options)
7
+ * 1. Explicit config (passed to ValidationOrchestrator/readiness options)
8
8
  * 2. Environment variable
9
9
  * 3. Module-owned defaults (none for topology)
10
10
  *
package/src/index.js CHANGED
@@ -1,17 +1,25 @@
1
1
  'use strict';
2
2
 
3
- // Mock infrastructure components (load first - no dependencies)
3
+ /**
4
+ * @module @onlineapps/conn-orch-validator
5
+ * @description Service validation framework using the operations.json contract.
6
+ *
7
+ * Production entry point: {@link ValidationOrchestrator} (6-step pre-validation
8
+ * driven by operations.json — OpenAPI path iteration is NOT supported).
9
+ *
10
+ * @see /api/docs/standards/operations-registry-contract.md §3 (operations.json)
11
+ * @see /api/docs/standards/validation-probe-contract.md (validation probes)
12
+ * @see /api/docs/architecture/validator.md (validator architecture)
13
+ */
14
+
4
15
  const MockMQClient = require('./mocks/MockMQClient');
5
16
  const MockRegistry = require('./mocks/MockRegistry');
6
17
  const MockStorage = require('./mocks/MockStorage');
7
18
 
8
- // Base test utilities (no circular dependencies)
9
- const ServiceValidator = require('./ServiceValidator');
10
19
  const CookbookTestUtils = require('./CookbookTestUtils');
11
20
  const { ServiceStructureValidator } = require('./validators/ServiceStructureValidator');
12
21
  const ValidationProofGenerator = require('./validators/ValidationProofGenerator');
13
22
 
14
- // Test runners (depend on mocks)
15
23
  let CookbookTestRunner;
16
24
  try {
17
25
  CookbookTestRunner = require('./CookbookTestRunner');
@@ -20,43 +28,29 @@ try {
20
28
  }
21
29
  const WorkflowTestRunner = require('./WorkflowTestRunner');
22
30
 
23
- // Orchestrators (depend on validators and runners)
24
31
  const ServiceReadinessValidator = require('./ServiceReadinessValidator');
25
- const TestOrchestrator = require('./TestOrchestrator');
26
- const ServiceTestHarness = require('./ServiceTestHarness');
27
32
  const ValidationOrchestrator = require('./ValidationOrchestrator');
28
33
 
29
- // Test helpers (generic test suite creators)
30
34
  const { createServiceReadinessTests } = require('./helpers/createServiceReadinessTests');
31
35
  const { createPreValidationTests } = require('./helpers/createPreValidationTests');
32
36
 
33
- // Export all components with getters to avoid circular dependency issues
34
37
  module.exports = {
35
- // Mocks
36
38
  get MockMQClient() { return MockMQClient; },
37
39
  get MockRegistry() { return MockRegistry; },
38
40
  get MockStorage() { return MockStorage; },
39
41
 
40
- // Test utilities
41
- get ServiceTestHarness() { return ServiceTestHarness; },
42
- get ServiceValidator() { return ServiceValidator; },
43
42
  get WorkflowTestRunner() { return WorkflowTestRunner; },
44
43
  get CookbookTestUtils() { return CookbookTestUtils; },
45
44
  get ServiceReadinessValidator() { return ServiceReadinessValidator; },
46
- get TestOrchestrator() { return TestOrchestrator; },
47
45
  get CookbookTestRunner() { return CookbookTestRunner; },
48
46
  get ValidationProofGenerator() { return ValidationProofGenerator; },
49
47
  get ServiceStructureValidator() { return ServiceStructureValidator; },
50
48
  get ValidationOrchestrator() { return ValidationOrchestrator; },
51
49
 
52
- // Test helpers (NEW - generic test suite creators)
53
50
  get createServiceReadinessTests() { return createServiceReadinessTests; },
54
51
  get createPreValidationTests() { return createPreValidationTests; },
55
52
 
56
- // Convenience factory functions
57
- createTestHarness: (options) => new ServiceTestHarness(options),
58
- createValidator: (options) => new ServiceValidator(options),
59
53
  createMockMQ: () => new MockMQClient(),
60
54
  createMockRegistry: () => new MockRegistry(),
61
55
  createMockStorage: () => new MockStorage()
62
- };
56
+ };
@@ -1,250 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Example: How service-wrapper uses connector-testing
5
- * Shows the integration between service-wrapper and testing framework
6
- */
7
-
8
- const { ServiceReadinessValidator, TestOrchestrator } = require('../src');
9
-
10
- /**
11
- * Enhanced ServiceWrapper with integrated testing
12
- */
13
- class ServiceWrapperWithTesting {
14
- constructor(options) {
15
- this.service = options.service;
16
- this.serviceName = options.serviceName;
17
- this.openApiSpec = options.openApiSpec;
18
- this.config = options.config;
19
-
20
- // Testing configuration
21
- this.testingEnabled = options.testingEnabled !== false;
22
- this.testLevel = options.testLevel || 'component'; // unit, component, or integration
23
- this.validator = new ServiceReadinessValidator();
24
- }
25
-
26
- /**
27
- * Start service with validation
28
- */
29
- async start() {
30
- console.log(`Starting ${this.serviceName}...`);
31
-
32
- // Step 1: Pre-start validation
33
- if (this.testingEnabled) {
34
- const validation = await this.validateBeforeStart();
35
-
36
- if (!validation.ready) {
37
- throw new Error(`Service validation failed: ${validation.recommendation}`);
38
- }
39
-
40
- console.log(`Validation passed with score: ${validation.score}/100`);
41
- }
42
-
43
- // Step 2: Start the actual service
44
- await this.startService();
45
-
46
- // Step 3: Post-start verification
47
- if (this.testingEnabled) {
48
- await this.verifyAfterStart();
49
- }
50
-
51
- console.log(`${this.serviceName} started successfully`);
52
- }
53
-
54
- /**
55
- * Validate service before starting
56
- */
57
- async validateBeforeStart() {
58
- console.log('Running pre-start validation...');
59
-
60
- // Use TestOrchestrator for comprehensive testing
61
- const orchestrator = new TestOrchestrator({
62
- service: this.service,
63
- serviceName: this.serviceName,
64
- openApiSpec: this.openApiSpec
65
- });
66
-
67
- // Run tests based on configured level
68
- let testResults;
69
- switch (this.testLevel) {
70
- case 'unit':
71
- testResults = await orchestrator.runUnitTests();
72
- break;
73
- case 'component':
74
- testResults = await orchestrator.runComponentTests();
75
- break;
76
- case 'integration':
77
- testResults = await orchestrator.runIntegrationTests();
78
- break;
79
- default:
80
- testResults = await orchestrator.runComponentTests();
81
- }
82
-
83
- // Convert test results to readiness format
84
- return {
85
- ready: testResults.passed,
86
- score: testResults.coverage || 0,
87
- recommendation: testResults.passed
88
- ? 'Service passed validation'
89
- : 'Service failed validation tests',
90
- details: testResults
91
- };
92
- }
93
-
94
- /**
95
- * Start the actual service
96
- */
97
- async startService() {
98
- // This would contain the actual service startup logic
99
- // - Start Express server
100
- // - Connect to MQ
101
- // - Register with registry
102
- // - etc.
103
-
104
- return new Promise((resolve) => {
105
- const PORT = this.config.port || 3000;
106
- this.server = this.service.listen(PORT, () => {
107
- console.log(`Service listening on port ${PORT}`);
108
- resolve();
109
- });
110
- });
111
- }
112
-
113
- /**
114
- * Verify service after start
115
- */
116
- async verifyAfterStart() {
117
- console.log('Running post-start verification...');
118
-
119
- const serviceUrl = `http://localhost:${this.config.port || 3000}`;
120
-
121
- // Quick readiness check
122
- const readiness = await this.validator.validateReadiness({
123
- name: this.serviceName,
124
- url: serviceUrl,
125
- openApiSpec: this.openApiSpec,
126
- healthEndpoint: '/health'
127
- });
128
-
129
- if (!readiness.ready) {
130
- console.warn('Post-start verification found issues:', readiness.errors);
131
- }
132
-
133
- return readiness;
134
- }
135
-
136
- /**
137
- * Stop service
138
- */
139
- async stop() {
140
- if (this.server) {
141
- await new Promise((resolve) => {
142
- this.server.close(resolve);
143
- });
144
- }
145
- }
146
- }
147
-
148
- // === Example Usage ===
149
-
150
- async function demonstrateUsage() {
151
- const express = require('express');
152
-
153
- // Create a simple service
154
- const app = express();
155
- app.use(express.json());
156
-
157
- app.get('/health', (req, res) => {
158
- res.json({ status: 'healthy' });
159
- });
160
-
161
- app.post('/api/process', (req, res) => {
162
- res.json({ processed: true, data: req.body });
163
- });
164
-
165
- // OpenAPI spec
166
- const openApiSpec = {
167
- openapi: '3.0.0',
168
- info: { title: 'Demo Service', version: '1.0.0' },
169
- paths: {
170
- '/health': {
171
- get: {
172
- operationId: 'healthCheck',
173
- responses: {
174
- '200': {
175
- content: {
176
- 'application/json': {
177
- schema: {
178
- type: 'object',
179
- properties: {
180
- status: { type: 'string' }
181
- }
182
- }
183
- }
184
- }
185
- }
186
- }
187
- }
188
- },
189
- '/api/process': {
190
- post: {
191
- operationId: 'processData',
192
- requestBody: {
193
- content: {
194
- 'application/json': {
195
- schema: { type: 'object' }
196
- }
197
- }
198
- },
199
- responses: {
200
- '200': {
201
- content: {
202
- 'application/json': {
203
- schema: { type: 'object' }
204
- }
205
- }
206
- }
207
- }
208
- }
209
- }
210
- }
211
- };
212
-
213
- // Create wrapper with testing
214
- const wrapper = new ServiceWrapperWithTesting({
215
- service: app,
216
- serviceName: 'demo-service',
217
- openApiSpec,
218
- config: {
219
- port: 3333
220
- },
221
- testingEnabled: true,
222
- testLevel: 'unit' // Start with unit tests for speed
223
- });
224
-
225
- try {
226
- // Start service (will run validation first)
227
- await wrapper.start();
228
-
229
- console.log('\nService is running with validation!');
230
- console.log('Try: curl http://localhost:3333/health');
231
-
232
- // Keep running for demo
233
- await new Promise(resolve => setTimeout(resolve, 5000));
234
-
235
- // Stop service
236
- await wrapper.stop();
237
- console.log('\nService stopped');
238
-
239
- } catch (error) {
240
- console.error('Failed to start service:', error.message);
241
- process.exit(1);
242
- }
243
- }
244
-
245
- // Run demonstration
246
- if (require.main === module) {
247
- demonstrateUsage().catch(console.error);
248
- }
249
-
250
- module.exports = { ServiceWrapperWithTesting };