UNPKG

@ones-op/node-host

Version:
112 lines (111 loc) 4.58 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HttpServer = void 0; const koa_1 = __importDefault(require("koa")); const koa_router_1 = __importDefault(require("koa-router")); const config_1 = require("../config"); const logger_1 = require("../logger"); const handler_1 = require("../handler"); const bodyParser = require("koa-bodyparser"); const lodash = require("lodash"); const api_1 = require("@opentelemetry/api"); const semantic_conventions_1 = require("@opentelemetry/semantic-conventions"); class HttpServer { constructor(port) { const app = new koa_1.default(); const router = new koa_router_1.default(); const tracer = api_1.trace.getTracer('http-server', '1.0.0'); // add trace app.use(async (ctx, next) => { let spanName = ctx.method; const route = ctx._matchedRoute; if (route) { spanName = `${spanName} ${route}`; } const activeContext = api_1.propagation.extract(api_1.context.active(), ctx.request.headers); await tracer.startActiveSpan(spanName, { attributes: { [semantic_conventions_1.ATTR_URL_FULL]: ctx.request.url, [semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD]: ctx.request.method, }, }, activeContext, async (span) => { try { return await next(); } catch (error) { span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: String(error) }); throw error; } finally { span.setAttribute(semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE, ctx.response.status); span.end(); } }); }); // log url app.use(async (ctx, next) => { logger_1.logger.debug(`Process ${ctx.request.method} ${ctx.request.url}`); await next(); logger_1.logger.debug(`Process ${ctx.request.method} ${ctx.request.url} finished reponse with code:${ctx.response.status} bodylength:${ctx.response.length}`); }); router.get('/healthz', (ctx) => { ctx.response.body = { status: 'ok', version: config_1.config.plugin.app_version, }; }); router.post('/plugin-call', this.copyPBBody, handler_1.HttpHandler.handlePBPluginCall); // 遍历 pluginConfig.extension 并注册路由 config_1.pluginConfig?.extension?.forEach((extensionItem) => { lodash.forEach(extensionItem, (providerConfig, provider) => { providerConfig?.funcs?.forEach((func, index) => { const routePath = `/backend/extension/${providerConfig.provider}/${func.name}`; router.post(routePath, this.createBodyParser, async (ctx) => { await handler_1.HttpHandler.extensionFuncHandler(ctx, routePath, func.url); }); }); }); }); app.use(router.routes()).use(router.allowedMethods()); app.listen(port); logger_1.logger.info(`Server is running on port ${port}`); } async copyPBBody(ctx, next) { try { ctx.request.body = await new Promise((resolve, reject) => { const chunks = []; ctx.req.on('data', (chunk) => { chunks.push(chunk); }); ctx.req.on('end', () => { resolve(Buffer.concat(chunks)); }); ctx.req.on('error', (err) => { reject(err); }); }); await next(); } catch (error) { logger_1.logger.error('Error in copyPBBody middleware', error); ctx.status = 500; ctx.body = 'Internal server error'; } } async createBodyParser(ctx, next) { try { await bodyParser({ enableTypes: ['json', 'form', 'text', 'xml'], })(ctx, next); } catch (error) { logger_1.logger.error('Error in createBodyParser', error); ctx.status = 500; ctx.body = 'Internal server error'; } } } exports.HttpServer = HttpServer;