107 lines
3.5 KiB
JavaScript
107 lines
3.5 KiB
JavaScript
'use strict';
|
|
|
|
const http = require('node:http');
|
|
const { spawn } = require('node:child_process');
|
|
const path = require('node:path');
|
|
const { createLogger, createModuleServer, loadManifest } = require('./platform-module-sdk.cjs');
|
|
|
|
const manifest = loadManifest(path.join(__dirname, 'module.json'));
|
|
const logger = createLogger({ moduleId: manifest.id });
|
|
const basePath = process.env.HUB_BASE_PATH || `/${manifest.slug}`;
|
|
const nextPort = 3001;
|
|
let shuttingDown = false;
|
|
|
|
const nextServer = spawn(process.execPath, ['server.js'], {
|
|
cwd: __dirname,
|
|
env: { ...process.env, HOSTNAME: '127.0.0.1', PORT: String(nextPort) },
|
|
stdio: 'inherit',
|
|
});
|
|
|
|
nextServer.once('exit', (code) => {
|
|
if (shuttingDown) return;
|
|
logger.error('Next.js-Prozess wurde beendet', { code });
|
|
process.exit(code || 1);
|
|
});
|
|
|
|
const server = createModuleServer({
|
|
manifest,
|
|
logger,
|
|
identityRequired: true,
|
|
routes(request, response, context) {
|
|
// Next.js treats the configured base path itself as the canonical root
|
|
// (without a trailing slash). Keep `/kalendartool` stable when MPM routes
|
|
// an incoming `/kalendartool` request as the module path `/`.
|
|
const modulePath = context.url.pathname === '/' ? '' : context.url.pathname;
|
|
const targetPath = `${basePath}${modulePath}${context.url.search}`;
|
|
const headers = { ...request.headers, host: `127.0.0.1:${nextPort}` };
|
|
for (const name of Object.keys(headers)) {
|
|
if (name.startsWith('x-kalendartool-mpm-')) delete headers[name];
|
|
}
|
|
headers['x-kalendartool-mpm-user-id'] = context.identity.userId;
|
|
headers['x-kalendartool-mpm-username'] = context.identity.username;
|
|
headers['x-kalendartool-mpm-display-name'] = context.identity.displayName || context.identity.username;
|
|
headers['x-kalendartool-mpm-role'] = context.identity.role;
|
|
|
|
const upstream = http.request({
|
|
host: '127.0.0.1',
|
|
port: nextPort,
|
|
method: request.method,
|
|
path: targetPath,
|
|
headers,
|
|
}, (upstreamResponse) => {
|
|
response.writeHead(upstreamResponse.statusCode || 502, upstreamResponse.headers);
|
|
upstreamResponse.pipe(response);
|
|
});
|
|
upstream.on('error', () => {
|
|
if (!response.headersSent) {
|
|
response.writeHead(502, { 'Content-Type': 'application/json' });
|
|
response.end(JSON.stringify({ statusCode: 502, message: 'Kalendertool ist noch nicht bereit' }));
|
|
} else {
|
|
response.end();
|
|
}
|
|
});
|
|
request.pipe(upstream);
|
|
},
|
|
});
|
|
|
|
function waitForNext(attempt = 0) {
|
|
const probe = http.get({
|
|
host: '127.0.0.1',
|
|
port: nextPort,
|
|
path: `${basePath}/api/manifest`,
|
|
headers: {
|
|
'x-kalendartool-mpm-user-id': 'readiness-probe',
|
|
'x-kalendartool-mpm-username': 'readiness-probe',
|
|
'x-kalendartool-mpm-display-name': 'readiness-probe',
|
|
'x-kalendartool-mpm-role': 'USER',
|
|
},
|
|
}, (response) => {
|
|
response.resume();
|
|
if (response.statusCode === 200) {
|
|
const port = Number(process.env.PORT || manifest.port);
|
|
server.listen(port, '0.0.0.0', () => logger.info('MPM-Modulserver gestartet', { port }));
|
|
return;
|
|
}
|
|
retry(attempt);
|
|
});
|
|
probe.on('error', () => retry(attempt));
|
|
}
|
|
|
|
function retry(attempt) {
|
|
if (attempt >= 119) {
|
|
logger.error('Next.js wurde nicht rechtzeitig bereit');
|
|
process.exit(1);
|
|
}
|
|
setTimeout(() => waitForNext(attempt + 1), 250);
|
|
}
|
|
|
|
waitForNext();
|
|
|
|
function shutdown() {
|
|
shuttingDown = true;
|
|
if (server.listening) server.close();
|
|
nextServer.kill('SIGTERM');
|
|
}
|
|
process.once('SIGTERM', shutdown);
|
|
process.once('SIGINT', shutdown);
|