@onlineapps/service-wrapper 2.0.18 → 2.0.19
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/MIGRATION_FROM_OPENAPI.md +9 -11
- package/docs/archived-2025-09-29/SERVICE_TESTING_STANDARD.md +2 -2
- package/jest.config.js +8 -8
- package/package.json +5 -4
- package/src/ServiceWrapper.js +58 -5
- package/{test → tests}/component/ServiceWrapper.component.test.js +1 -1
- package/{test → tests}/component/connector-integration.test.js +1 -1
- package/{test → tests}/e2e/full-flow.test.js +1 -1
- package/{test → tests}/monitoring-integration.test.js +1 -1
- package/{test → tests}/unit/ServiceWrapper.test.js +1 -1
- /package/{test → tests}/integration/orchestrator-integration.test.js +0 -0
- /package/{test → tests}/mocks/connectors.js +0 -0
- /package/{test → tests}/run-tests.js +0 -0
- /package/{test → tests}/setup.js +0 -0
|
@@ -110,7 +110,7 @@ Transform your OpenAPI spec into Operations format:
|
|
|
110
110
|
```bash
|
|
111
111
|
# Old structure
|
|
112
112
|
services/my-service/
|
|
113
|
-
├──
|
|
113
|
+
├── conn-config/
|
|
114
114
|
│ ├── manifest.json
|
|
115
115
|
│ └── openapi.json
|
|
116
116
|
|
|
@@ -121,17 +121,14 @@ services/my-service/
|
|
|
121
121
|
│ └── operations.json
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
Convert configuration:
|
|
125
125
|
```bash
|
|
126
126
|
cd services/my-service
|
|
127
|
-
mkdir -p conn-config
|
|
128
127
|
|
|
129
|
-
# If you have existing
|
|
130
|
-
|
|
128
|
+
# If you have existing manifest.json, merge it into config.json
|
|
129
|
+
# Move from manifest.json to config.json structure
|
|
131
130
|
|
|
132
131
|
# Create operations.json (see conversion below)
|
|
133
|
-
# Delete old directory
|
|
134
|
-
rm -rf connector-config/
|
|
135
132
|
```
|
|
136
133
|
|
|
137
134
|
### Step 3: Convert OpenAPI to Operations
|
|
@@ -153,11 +150,12 @@ Use this mapping:
|
|
|
153
150
|
#### Before:
|
|
154
151
|
```javascript
|
|
155
152
|
const { ServiceWrapper } = require('@onlineapps/service-wrapper');
|
|
156
|
-
const openApiSpec = require('./
|
|
153
|
+
const openApiSpec = require('./conn-config/openapi.json');
|
|
157
154
|
|
|
158
155
|
const wrapper = new ServiceWrapper({
|
|
159
156
|
app,
|
|
160
157
|
server,
|
|
158
|
+
serviceRoot: __dirname,
|
|
161
159
|
config,
|
|
162
160
|
openApiSpec // OLD
|
|
163
161
|
});
|
|
@@ -171,6 +169,7 @@ const operations = require('./conn-config/operations.json');
|
|
|
171
169
|
const wrapper = new ServiceWrapper({
|
|
172
170
|
app,
|
|
173
171
|
server,
|
|
172
|
+
serviceRoot: __dirname,
|
|
174
173
|
config,
|
|
175
174
|
operations // NEW
|
|
176
175
|
});
|
|
@@ -181,7 +180,7 @@ const wrapper = new ServiceWrapper({
|
|
|
181
180
|
#### Before:
|
|
182
181
|
```javascript
|
|
183
182
|
app.get('/specification', (req, res) => {
|
|
184
|
-
const openapi = require('./
|
|
183
|
+
const openapi = require('./conn-config/openapi.json');
|
|
185
184
|
res.json(openapi);
|
|
186
185
|
});
|
|
187
186
|
```
|
|
@@ -197,7 +196,6 @@ app.get('/specification', (req, res) => {
|
|
|
197
196
|
### Step 6: Update Documentation References
|
|
198
197
|
|
|
199
198
|
Update all references:
|
|
200
|
-
- `connector-config/` → `conn-config/`
|
|
201
199
|
- `openapi.json` → `operations.json`
|
|
202
200
|
- "OpenAPI specification" → "Operations specification"
|
|
203
201
|
|
|
@@ -271,7 +269,7 @@ function convertSchema(schema) {
|
|
|
271
269
|
}
|
|
272
270
|
|
|
273
271
|
// Usage
|
|
274
|
-
const openapi = require('./
|
|
272
|
+
const openapi = require('./conn-config/openapi.json');
|
|
275
273
|
const operations = convertOpenAPIToOperations(openapi);
|
|
276
274
|
fs.writeFileSync('./conn-config/operations.json', JSON.stringify(operations, null, 2));
|
|
277
275
|
console.log('Converted to operations.json');
|
|
@@ -365,7 +365,7 @@ servers:
|
|
|
365
365
|
description: Configured base URL
|
|
366
366
|
```
|
|
367
367
|
|
|
368
|
-
## 9. Testing with conn-
|
|
368
|
+
## 9. Testing with conn-orch-validator
|
|
369
369
|
|
|
370
370
|
The connector testing framework will:
|
|
371
371
|
1. Load your OpenAPI schema
|
|
@@ -386,4 +386,4 @@ Ensure your service is ready by:
|
|
|
386
386
|
- [JSON Schema Validation](https://json-schema.org/draft/2019-09/json-schema-validation.html)
|
|
387
387
|
- [swagger-cli Documentation](https://apitools.dev/swagger-cli/)
|
|
388
388
|
- Service Wrapper documentation: `/shared/connector/service-wrapper/README.md`
|
|
389
|
-
- Testing examples: `/shared/connector/conn-
|
|
389
|
+
- Testing examples: `/shared/connector/conn-orch-validator/examples/`
|
package/jest.config.js
CHANGED
|
@@ -7,7 +7,7 @@ module.exports = {
|
|
|
7
7
|
'!src/**/index.js'
|
|
8
8
|
],
|
|
9
9
|
testMatch: [
|
|
10
|
-
'**/
|
|
10
|
+
'**/tests/**/*.test.js'
|
|
11
11
|
],
|
|
12
12
|
testPathIgnorePatterns: [
|
|
13
13
|
'/node_modules/'
|
|
@@ -22,13 +22,13 @@ module.exports = {
|
|
|
22
22
|
},
|
|
23
23
|
moduleNameMapper: {
|
|
24
24
|
// Map connector imports to mocks in unit tests
|
|
25
|
-
'@onlineapps/conn-infra-mq': '<rootDir>/
|
|
26
|
-
'@onlineapps/conn-orch-registry': '<rootDir>/
|
|
27
|
-
'@onlineapps/conn-base-logger': '<rootDir>/
|
|
28
|
-
'@onlineapps/conn-orch-orchestrator': '<rootDir>/
|
|
29
|
-
'@onlineapps/conn-orch-api-mapper': '<rootDir>/
|
|
30
|
-
'@onlineapps/conn-orch-cookbook': '<rootDir>/
|
|
25
|
+
'@onlineapps/conn-infra-mq': '<rootDir>/tests/mocks/connectors.js',
|
|
26
|
+
'@onlineapps/conn-orch-registry': '<rootDir>/tests/mocks/connectors.js',
|
|
27
|
+
'@onlineapps/conn-base-logger': '<rootDir>/tests/mocks/connectors.js',
|
|
28
|
+
'@onlineapps/conn-orch-orchestrator': '<rootDir>/tests/mocks/connectors.js',
|
|
29
|
+
'@onlineapps/conn-orch-api-mapper': '<rootDir>/tests/mocks/connectors.js',
|
|
30
|
+
'@onlineapps/conn-orch-cookbook': '<rootDir>/tests/mocks/connectors.js'
|
|
31
31
|
},
|
|
32
|
-
setupFilesAfterEnv: ['<rootDir>/
|
|
32
|
+
setupFilesAfterEnv: ['<rootDir>/tests/setup.js'],
|
|
33
33
|
verbose: true
|
|
34
34
|
};
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlineapps/service-wrapper",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.19",
|
|
4
4
|
"description": "Thin orchestration layer for microservices - delegates all infrastructure concerns to specialized connectors",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "jest",
|
|
8
|
-
"test:unit": "jest
|
|
9
|
-
"test:component": "jest
|
|
10
|
-
"test:integration": "jest
|
|
8
|
+
"test:unit": "jest tests/unit",
|
|
9
|
+
"test:component": "jest tests/component",
|
|
10
|
+
"test:integration": "jest tests/integration",
|
|
11
11
|
"test:coverage": "jest --coverage",
|
|
12
12
|
"test:mocked": "node test/run-tests.js",
|
|
13
13
|
"docs": "jsdoc2md --files src/**/*.js > API.md",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"@onlineapps/conn-orch-cookbook": "^2.0.0",
|
|
33
33
|
"@onlineapps/conn-orch-orchestrator": "^1.0.1",
|
|
34
34
|
"@onlineapps/conn-orch-registry": "^1.1.13",
|
|
35
|
+
"@onlineapps/conn-orch-validator": "^2.0.0",
|
|
35
36
|
"@onlineapps/monitoring-core": "^1.0.0"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
package/src/ServiceWrapper.js
CHANGED
|
@@ -21,6 +21,7 @@ const ApiMapperConnector = require('@onlineapps/conn-orch-api-mapper');
|
|
|
21
21
|
const CookbookConnector = require('@onlineapps/conn-orch-cookbook');
|
|
22
22
|
const CacheConnector = require('@onlineapps/conn-base-cache');
|
|
23
23
|
const ErrorHandlerConnector = require('@onlineapps/conn-infra-error-handler');
|
|
24
|
+
const { ValidationOrchestrator } = require('@onlineapps/conn-orch-validator');
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* ServiceWrapper class
|
|
@@ -34,6 +35,7 @@ class ServiceWrapper {
|
|
|
34
35
|
* @param {Object} options.server - HTTP server instance
|
|
35
36
|
* @param {Object} options.config - Service and wrapper configuration
|
|
36
37
|
* @param {Object} options.operations - Operations schema
|
|
38
|
+
* @param {string} [options.serviceRoot] - Service root directory (for validation)
|
|
37
39
|
* @param {Object} [options.validationProof=null] - Optional validation proof {hash, data}
|
|
38
40
|
*/
|
|
39
41
|
constructor(options = {}) {
|
|
@@ -44,6 +46,7 @@ class ServiceWrapper {
|
|
|
44
46
|
this.server = options.server;
|
|
45
47
|
this.config = this._processConfig(options.config);
|
|
46
48
|
this.operations = options.operations;
|
|
49
|
+
this.serviceRoot = options.serviceRoot;
|
|
47
50
|
this.validationProof = options.validationProof || null;
|
|
48
51
|
|
|
49
52
|
// Initialize connector placeholders
|
|
@@ -146,27 +149,34 @@ class ServiceWrapper {
|
|
|
146
149
|
await this._initializeMonitoring();
|
|
147
150
|
}
|
|
148
151
|
|
|
149
|
-
// 2.
|
|
152
|
+
// 2. Run pre-validation (Tier 1)
|
|
153
|
+
// Validates service structure, config, operations, cookbook tests
|
|
154
|
+
// Skips if valid proof exists in conn-runtime/validation-proof.json
|
|
155
|
+
if (this.serviceRoot && this.config.wrapper?.validation?.enabled !== false) {
|
|
156
|
+
await this._ensureValidationProof();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// 3. Initialize MQ connection
|
|
150
160
|
if (this.config.wrapper?.mq?.enabled !== false) {
|
|
151
161
|
await this._initializeMQ();
|
|
152
162
|
}
|
|
153
163
|
|
|
154
|
-
//
|
|
164
|
+
// 4. Initialize service registry
|
|
155
165
|
if (this.config.wrapper?.registry?.enabled !== false) {
|
|
156
166
|
await this._initializeRegistry();
|
|
157
167
|
}
|
|
158
168
|
|
|
159
|
-
//
|
|
169
|
+
// 5. Initialize cache if configured
|
|
160
170
|
if (this.config.wrapper?.cache?.enabled === true) {
|
|
161
171
|
await this._initializeCache();
|
|
162
172
|
}
|
|
163
173
|
|
|
164
|
-
//
|
|
174
|
+
// 6. Setup health checks
|
|
165
175
|
if (this.config.wrapper?.health?.enabled !== false) {
|
|
166
176
|
this._setupHealthChecks();
|
|
167
177
|
}
|
|
168
178
|
|
|
169
|
-
//
|
|
179
|
+
// 7. Initialize orchestrator for workflow processing
|
|
170
180
|
// NOTE: Orchestrator is prepared but workflow listeners will be started
|
|
171
181
|
// ONLY after receiving certificate from Registry (see _initializeRegistry)
|
|
172
182
|
if (this.mqClient) {
|
|
@@ -658,6 +668,49 @@ class ServiceWrapper {
|
|
|
658
668
|
}
|
|
659
669
|
}
|
|
660
670
|
|
|
671
|
+
/**
|
|
672
|
+
* Ensure validation proof exists and is valid
|
|
673
|
+
* Runs ValidationOrchestrator if proof missing or invalid
|
|
674
|
+
* @private
|
|
675
|
+
*/
|
|
676
|
+
async _ensureValidationProof() {
|
|
677
|
+
if (!this.config.service?.name) {
|
|
678
|
+
throw new Error('Service name is required for validation');
|
|
679
|
+
}
|
|
680
|
+
if (!this.config.service?.version) {
|
|
681
|
+
throw new Error('Service version is required for validation');
|
|
682
|
+
}
|
|
683
|
+
if (!this.logger) {
|
|
684
|
+
throw new Error('Monitoring must be initialized before validation');
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
const { name: serviceName, version: serviceVersion } = this.config.service;
|
|
688
|
+
|
|
689
|
+
this.logger.info('[ServiceWrapper] Checking validation proof...');
|
|
690
|
+
|
|
691
|
+
const orchestrator = new ValidationOrchestrator({
|
|
692
|
+
serviceRoot: this.serviceRoot,
|
|
693
|
+
serviceName,
|
|
694
|
+
serviceVersion,
|
|
695
|
+
logger: this.logger
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
const result = await orchestrator.validate();
|
|
699
|
+
|
|
700
|
+
if (!result.success) {
|
|
701
|
+
throw new Error(`Validation failed: ${result.errors.join(', ')}`);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
if (result.skipped) {
|
|
705
|
+
this.logger.info('[ServiceWrapper] ✓ Using existing validation proof');
|
|
706
|
+
} else {
|
|
707
|
+
this.logger.info('[ServiceWrapper] ✓ Validation completed successfully');
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// Store proof for registration
|
|
711
|
+
this.validationProof = result.proof;
|
|
712
|
+
}
|
|
713
|
+
|
|
661
714
|
/**
|
|
662
715
|
* Get wrapper status
|
|
663
716
|
*/
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
const ServiceWrapper = require('../../src/ServiceWrapper');
|
|
10
10
|
const express = require('express');
|
|
11
11
|
|
|
12
|
-
describe('ServiceWrapper Component Tests', () => {
|
|
12
|
+
describe('ServiceWrapper Component Tests @component', () => {
|
|
13
13
|
let wrapper;
|
|
14
14
|
let app;
|
|
15
15
|
let server;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Run these after implementing each connector
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
describe('Connector Integration Tests', () => {
|
|
9
|
+
describe('Connector Integration Tests @component', () => {
|
|
10
10
|
describe('Orchestrator Connector', () => {
|
|
11
11
|
test.skip('should integrate with real Orchestrator connector', async () => {
|
|
12
12
|
// Enable this test after conn-orch-orchestrator is fully implemented
|
|
@@ -10,7 +10,7 @@ const MQConnector = require('@onlineapps/conn-infra-mq');
|
|
|
10
10
|
const express = require('express');
|
|
11
11
|
const http = require('http');
|
|
12
12
|
|
|
13
|
-
describe('ServiceWrapper E2E Tests', () => {
|
|
13
|
+
describe('ServiceWrapper E2E Tests @e2e', () => {
|
|
14
14
|
let testService;
|
|
15
15
|
let testServer;
|
|
16
16
|
let serviceWrapper;
|
|
@@ -20,7 +20,7 @@ jest.mock('@onlineapps/conn-orch-orchestrator', () => MockOrchestratorConnector)
|
|
|
20
20
|
jest.mock('@onlineapps/conn-orch-api-mapper', () => MockApiMapperConnector);
|
|
21
21
|
jest.mock('@onlineapps/conn-orch-cookbook', () => MockCookbookConnector);
|
|
22
22
|
|
|
23
|
-
describe('ServiceWrapper Unit Tests', () => {
|
|
23
|
+
describe('ServiceWrapper Unit Tests @unit', () => {
|
|
24
24
|
let wrapper;
|
|
25
25
|
let mockExpressApp;
|
|
26
26
|
let mockOpenApiSpec;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/{test → tests}/setup.js
RENAMED
|
File without changes
|