@onlineapps/service-wrapper 2.1.7 → 2.1.10
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 +17 -2
- package/src/index.js +92 -1
package/package.json
CHANGED
package/src/ServiceWrapper.js
CHANGED
|
@@ -273,6 +273,7 @@ class ServiceWrapper {
|
|
|
273
273
|
* @private
|
|
274
274
|
*/
|
|
275
275
|
_logPhase(phase, phaseName, status, error = null, duration = null) {
|
|
276
|
+
const serviceName = this.config.service?.name || 'unnamed-service';
|
|
276
277
|
const logMsg = `[FÁZE ${phase}] ${phaseName} - ${status}`;
|
|
277
278
|
const logData = {
|
|
278
279
|
phase,
|
|
@@ -281,8 +282,19 @@ class ServiceWrapper {
|
|
|
281
282
|
timestamp: new Date().toISOString(),
|
|
282
283
|
duration,
|
|
283
284
|
error: error ? { message: error.message, stack: error.stack } : null,
|
|
284
|
-
serviceName
|
|
285
|
+
serviceName
|
|
285
286
|
};
|
|
287
|
+
|
|
288
|
+
// Structured log for service wrapper phases
|
|
289
|
+
console.log(`[${serviceName}:service-wrapper:init:PHASE_${status}] ${JSON.stringify({
|
|
290
|
+
timestamp: new Date().toISOString(),
|
|
291
|
+
service: serviceName,
|
|
292
|
+
phase,
|
|
293
|
+
phase_name: phaseName,
|
|
294
|
+
status,
|
|
295
|
+
duration_ms: duration,
|
|
296
|
+
error: error ? error.message : null
|
|
297
|
+
})}`);
|
|
286
298
|
|
|
287
299
|
if (status === 'PASSED') {
|
|
288
300
|
this.logger?.info(logMsg, logData);
|
|
@@ -1255,10 +1267,13 @@ class ServiceWrapper {
|
|
|
1255
1267
|
}
|
|
1256
1268
|
|
|
1257
1269
|
// Normalize message format: Gateway sends workflowId, orchestrator expects workflow_id
|
|
1270
|
+
// V2 format uses step_id, V1 used id - support both for backwards compatibility during migration
|
|
1271
|
+
const firstStep = message.cookbook?.steps?.[0];
|
|
1272
|
+
const firstStepId = firstStep?.step_id || firstStep?.id;
|
|
1258
1273
|
const normalizedMessage = {
|
|
1259
1274
|
...message,
|
|
1260
1275
|
workflow_id: message.workflow_id || message.workflowId,
|
|
1261
|
-
current_step: message.current_step ||
|
|
1276
|
+
current_step: message.current_step || firstStepId
|
|
1262
1277
|
};
|
|
1263
1278
|
|
|
1264
1279
|
// Validate normalized message has required fields
|
package/src/index.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* @since 2.0.0
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
const path = require('path');
|
|
14
15
|
const ServiceWrapper = require('./ServiceWrapper');
|
|
15
16
|
const { ConfigLoader } = require('./ConfigLoader');
|
|
16
17
|
|
|
@@ -21,8 +22,98 @@ const { ConfigLoader } = require('./ConfigLoader');
|
|
|
21
22
|
// Note: HTTP logging middleware is now in each service's middlewares/httpLogging.js
|
|
22
23
|
// It uses lazy logger access via lib/logger.js (set after wrapper.initialize())
|
|
23
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Bootstrap a business service with standard configuration
|
|
27
|
+
* Eliminates boilerplate code in service index.js
|
|
28
|
+
*
|
|
29
|
+
* @param {string} serviceRoot - Service root directory (__dirname from index.js)
|
|
30
|
+
* @param {Object} [options] - Optional overrides
|
|
31
|
+
* @param {Object} [options.app] - Express app (default: require('./src/app'))
|
|
32
|
+
* @param {Object} [options.config] - Config (default: require('./src/config'))
|
|
33
|
+
* @param {Function} [options.setLogger] - Logger setter (default: require('./src/lib/logger').setLogger)
|
|
34
|
+
* @returns {Promise<{wrapper: ServiceWrapper, server: Object}>}
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // index.js (minimal)
|
|
38
|
+
* require('@onlineapps/service-wrapper').bootstrap(__dirname);
|
|
39
|
+
*/
|
|
40
|
+
async function bootstrap(serviceRoot, options = {}) {
|
|
41
|
+
// Load dotenv first
|
|
42
|
+
require('dotenv').config({ path: path.join(serviceRoot, '.env') });
|
|
43
|
+
|
|
44
|
+
// Load app, config, and logger from service
|
|
45
|
+
const app = options.app || require(path.join(serviceRoot, 'src', 'app'));
|
|
46
|
+
const config = options.config || require(path.join(serviceRoot, 'src', 'config'));
|
|
47
|
+
|
|
48
|
+
// Logger setter is optional - some services may not have it
|
|
49
|
+
let setLogger = options.setLogger;
|
|
50
|
+
if (!setLogger) {
|
|
51
|
+
try {
|
|
52
|
+
const loggerModule = require(path.join(serviceRoot, 'src', 'lib', 'logger'));
|
|
53
|
+
setLogger = loggerModule.setLogger;
|
|
54
|
+
} catch (e) {
|
|
55
|
+
// No logger module - that's OK
|
|
56
|
+
setLogger = () => {};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
console.log(`Starting ${config.service.name} v${config.service.version}...`);
|
|
61
|
+
|
|
62
|
+
// 1. Start HTTP server
|
|
63
|
+
const PORT = config.service.port;
|
|
64
|
+
const server = app.listen(PORT, () => {
|
|
65
|
+
console.log(`✓ HTTP server listening on port ${PORT}`);
|
|
66
|
+
console.log(`✓ Health check: http://localhost:${PORT}/health`);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// 2. Initialize Service Wrapper (MQ, Registry, Monitoring, etc.)
|
|
70
|
+
const wrapper = new ServiceWrapper({
|
|
71
|
+
app,
|
|
72
|
+
server,
|
|
73
|
+
serviceRoot,
|
|
74
|
+
config: {
|
|
75
|
+
service: {
|
|
76
|
+
name: config.service.name,
|
|
77
|
+
version: config.service.version,
|
|
78
|
+
port: config.service.port,
|
|
79
|
+
url: process.env.SERVICE_URL || `http://localhost:${PORT}`
|
|
80
|
+
},
|
|
81
|
+
wrapper: config.wrapper
|
|
82
|
+
},
|
|
83
|
+
operations: config.operations,
|
|
84
|
+
validationProof: config.validationProof
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
await wrapper.initialize();
|
|
88
|
+
|
|
89
|
+
// Initialize centralized logger for use throughout the service
|
|
90
|
+
if (setLogger && wrapper.logger) {
|
|
91
|
+
setLogger(wrapper.logger);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.log(`✓ Service Wrapper initialized (MQ, Registry, Monitoring)`);
|
|
95
|
+
console.log(`✓ Local logs: logs/app.{date}.log`);
|
|
96
|
+
console.log(`✓ ${config.service.name} ready\n`);
|
|
97
|
+
|
|
98
|
+
// 3. Setup graceful shutdown
|
|
99
|
+
const shutdown = async () => {
|
|
100
|
+
console.log('\nShutting down gracefully...');
|
|
101
|
+
await wrapper.shutdown();
|
|
102
|
+
server.close(() => {
|
|
103
|
+
console.log('Server closed');
|
|
104
|
+
process.exit(0);
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
process.on('SIGTERM', shutdown);
|
|
109
|
+
process.on('SIGINT', shutdown);
|
|
110
|
+
|
|
111
|
+
return { wrapper, server };
|
|
112
|
+
}
|
|
113
|
+
|
|
24
114
|
module.exports = ServiceWrapper;
|
|
25
115
|
module.exports.ServiceWrapper = ServiceWrapper;
|
|
26
116
|
module.exports.ConfigLoader = ConfigLoader;
|
|
117
|
+
module.exports.bootstrap = bootstrap;
|
|
27
118
|
module.exports.default = ServiceWrapper;
|
|
28
|
-
module.exports.VERSION = '2.1.
|
|
119
|
+
module.exports.VERSION = '2.1.10';
|