UNPKG

@microfleet/core

Version:
147 lines (119 loc) 3.78 kB
import assert = require('assert') import { NotPermittedError } from 'common-errors' import { Plugin, Server, ServerOptions } from '@hapi/hapi' import Joi = require('@hapi/joi') import { ActionTransport, Microfleet } from '../../../..' import { PluginInterface } from '../../../../types' import attachRouter, { HapiRouterConfig } from './router/attach' import * as RequestTracker from '../../../router/request-tracker' export interface HapiPlugin { plugin: string | Plugin<any>; options?: any; once?: boolean; } const defaultPlugins: HapiPlugin[] = [{ options: {}, plugin: './plugins/redirect', }, { options: {}, plugin: './plugins/state', }] export interface HapiPluginConfig { server: { handlerConfig: { server: ServerOptions plugins: { list: any[] options?: any } views?: any } host?: string port?: number attachSocketIO?: boolean } router: HapiRouterConfig & { enabled: boolean } } function createHapiServer(config: HapiPluginConfig, service: Microfleet): PluginInterface { const { handlerConfig } = config.server handlerConfig.server.address = config.server.host || '0.0.0.0' handlerConfig.server.port = config.server.port ? config.server.port : 0 assert(service.hasPlugin('logger'), 'must include logger plugin') const server = service.http = new Server(handlerConfig.server) server.validator(Joi) let routerPlugin: HapiPlugin if (config.router.enabled) { routerPlugin = attachRouter(service, config.router) } // exposes microfleet inside the server for tighter integrations server.decorate('server', 'microfleet', service as any) async function initPlugins() { const { list, options } = handlerConfig.plugins const plugins = defaultPlugins.concat(list) if (handlerConfig.views) { plugins.push({ options: {}, plugin: '@hapi/vision', }) plugins.push({ options: handlerConfig.views, plugin: './plugins/views', }) } if (routerPlugin !== undefined) { plugins.push(routerPlugin) } const registrations = [] for (const pluguinConfiguration of plugins) { registrations.push({ options: pluguinConfiguration.options, plugin: typeof pluguinConfiguration.plugin === 'string' ? require(pluguinConfiguration.plugin) : pluguinConfiguration.plugin, }) } return server.register(registrations, options) } async function startServer() { if (config.server.attachSocketIO) { if (!service.socketIO) { throw new NotPermittedError('SocketIO plugin not found') } service.socketIO.listen(server.listener, (service.config.socketIO as any)?.options) } await initPlugins() await server.start() service.log.info( { transport: 'http', http: '@hapi/hapi' }, 'listening on http://%s:%s', handlerConfig.server.address, server.info.port ) service.emit('plugin:start:http', server) return server } function getRequestCount() { return RequestTracker.getRequestCount(service, ActionTransport.http) } async function stopServer() { const { started } = server.info if (started) { /* Socket depends on Http transport. Wait for its requests here */ /* Call of socketIO.close() causes all active connections close */ if (config.server.attachSocketIO) { await RequestTracker.waitForRequestsToFinish(service, ActionTransport.socketIO) } /* Server waits for connection finish anyway */ await server.stop() } service.emit('plugin:stop:http', server) } return { getRequestCount, close: stopServer, connect: startServer, } } export default createHapiServer