@onlineapps/service-wrapper 2.1.114 → 2.1.116

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/service-wrapper",
3
- "version": "2.1.114",
3
+ "version": "2.1.116",
4
4
  "description": "Thin orchestration layer for microservices - delegates all infrastructure concerns to specialized connectors",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -1092,15 +1092,20 @@ class ServiceWrapper {
1092
1092
  };
1093
1093
 
1094
1094
  if (this.mqClient) {
1095
- try {
1096
- const mqHealth = await this.mqClient.performHealthCheck();
1097
- health.components.mq = mqHealth.healthy ? 'healthy' : 'unhealthy';
1098
- if (!mqHealth.healthy) {
1099
- health.mqIssues = mqHealth.issues;
1095
+ const transport = this.mqClient._transport;
1096
+ if (transport && typeof transport.performHealthCheck === 'function') {
1097
+ try {
1098
+ const mqHealth = await transport.performHealthCheck();
1099
+ health.components.mq = mqHealth.healthy ? 'healthy' : 'unhealthy';
1100
+ if (!mqHealth.healthy) {
1101
+ health.mqIssues = mqHealth.issues;
1102
+ }
1103
+ } catch (e) {
1104
+ health.components.mq = 'unhealthy';
1105
+ health.mqIssues = [e.message];
1100
1106
  }
1101
- } catch (e) {
1102
- health.components.mq = 'unhealthy';
1103
- health.mqIssues = [e.message];
1107
+ } else {
1108
+ health.components.mq = this.mqClient.isConnected() ? 'healthy' : 'unhealthy';
1104
1109
  }
1105
1110
  }
1106
1111
 
@@ -1115,24 +1120,13 @@ class ServiceWrapper {
1115
1120
  res.json(health);
1116
1121
  };
1117
1122
 
1118
- // Insert health route BEFORE catch-all 404/error handlers in Express stack.
1119
- // Services register routes in app.js (loaded before ServiceWrapper), including
1120
- // 404 middleware. A plain app.get() would add AFTER the 404 handler and never match.
1121
- this.app.get(healthEndpoint, healthHandler);
1122
-
1123
- const stack = this.app._router?.stack;
1124
- if (stack && stack.length > 1) {
1125
- const healthLayer = stack.pop();
1126
- // Find first catch-all middleware (no route, not a built-in parser)
1127
- const builtins = new Set(['query', 'expressInit', 'jsonParser', 'urlencodedParser', 'tenantContext', 'router']);
1128
- let insertAt = stack.length;
1129
- for (let i = 0; i < stack.length; i++) {
1130
- if (!stack[i].route && !builtins.has(stack[i].name)) {
1131
- insertAt = i;
1132
- break;
1133
- }
1134
- }
1135
- stack.splice(insertAt, 0, healthLayer);
1123
+ // Health route must be registered BEFORE catch-all 404/error handlers.
1124
+ // Services register routes (including 404) in app.js before ServiceWrapper initializes.
1125
+ // We use _healthHandler reference that bootstrap() registered early in the stack.
1126
+ if (this._healthRouteRegistered) {
1127
+ this._healthImpl = healthHandler;
1128
+ } else {
1129
+ this.app.get(healthEndpoint, healthHandler);
1136
1130
  }
1137
1131
 
1138
1132
  this.logger?.info(`Health check endpoint registered at ${healthEndpoint}`);
package/src/index.js CHANGED
@@ -95,6 +95,31 @@ async function bootstrap(serviceRoot, options = {}) {
95
95
  stack.pop();
96
96
  stack.unshift(lastLayer);
97
97
 
98
+ // Register /health route BEFORE service's 404 handler.
99
+ // ServiceWrapper._setupHealthChecks() will later set _healthImpl with actual MQ checks.
100
+ // Until then, this returns a basic healthy response (service is starting up).
101
+ let wrapperRef = null;
102
+ const healthEndpoint = config.wrapper?.health?.endpoint || '/health';
103
+ app.get(healthEndpoint, async (req, res) => {
104
+ if (wrapperRef && wrapperRef._healthImpl) {
105
+ return wrapperRef._healthImpl(req, res);
106
+ }
107
+ res.json({ status: 'starting', service: config.service.name, timestamp: new Date().toISOString() });
108
+ });
109
+
110
+ // Move health route before 404/error handlers (same stack technique as tenant context)
111
+ const healthLayer = stack.pop();
112
+ if (healthLayer) {
113
+ const catchAllIdx = stack.findIndex((layer, i) =>
114
+ i > 0 && !layer.route && !['query', 'expressInit', 'jsonParser', 'urlencodedParser'].includes(layer.name)
115
+ );
116
+ if (catchAllIdx > 0) {
117
+ stack.splice(catchAllIdx, 0, healthLayer);
118
+ } else {
119
+ stack.push(healthLayer);
120
+ }
121
+ }
122
+
98
123
  // 1. Start HTTP server
99
124
  const PORT = config.service.port;
100
125
  const server = app.listen(PORT, () => {
@@ -123,7 +148,9 @@ async function bootstrap(serviceRoot, options = {}) {
123
148
  validationProof: config.validationProof
124
149
  });
125
150
 
151
+ wrapper._healthRouteRegistered = true;
126
152
  await wrapper.initialize();
153
+ wrapperRef = wrapper;
127
154
 
128
155
  // Initialize centralized logger for use throughout the service
129
156
  if (setLogger && wrapper.logger) {