/** @module core */ /** @hidden */ let process = require('process'); import { ConsoleLogger } from 'pip-services3-components-node'; import { ConfigParams } from 'pip-services3-commons-node'; import { Container } from './Container'; /** * Inversion of control (IoC) container that runs as a system process. * It processes command line arguments and handles unhandled exceptions and Ctrl-C signal * to gracefully shutdown the container. * * ### Command line arguments ### * - --config / -c path to JSON or YAML file with container configuration (default: "./config/config.yml") * - --param / --params / -p value(s) to parameterize the container configuration * - --help / -h prints the container usage help * * @see [[Container]] * * ### Example ### * * let container = new ProcessContainer(); * container.addFactory(new MyComponentFactory()); * * container.run(process.args); */ export class ProcessContainer extends Container { protected _configPath: string = './config/config.yml'; /** * Creates a new instance of the container. * * @param name (optional) a container name (accessible via ContextInfo) * @param description (optional) a container description (accessible via ContextInfo) */ public constructor(name?: string, description?: string) { super(name, description); this._logger = new ConsoleLogger(); } private getConfigPath(args: string[]): string { for (let index = 0; index < args.length; index++) { let arg = args[index]; let nextArg = index < args.length - 1 ? args[index + 1] : null; nextArg = nextArg && nextArg.startsWith('-') ? null : nextArg; if (nextArg != null) { if (arg == "--config" || arg == "-c") { return nextArg; } } } return this._configPath; } private getParameters(args: string[]): ConfigParams { // Process command line parameters let line = ''; for (let index = 0; index < args.length; index++) { let arg = args[index]; let nextArg = index < args.length - 1 ? args[index + 1] : null; nextArg = nextArg && nextArg.startsWith('-') ? null : nextArg; if (nextArg != null) { if (arg == "--param" || arg == "--params" || arg == "-p") { if (line.length > 0) line = line + ';'; line = line + nextArg; index++; } } } let parameters = ConfigParams.fromString(line); // Process environmental variables parameters.append(process.env); return parameters; } private showHelp(args: string[]) { for (let index = 0; index < args.length; index++) { let arg = args[index]; if (arg == "--help" || arg == "-h") return true; } return false; } private printHelp() { console.log("Pip.Services process container - http://www.github.com/pip-services/pip-services"); console.log("run [-h] [-c ] [-p =]*"); } private captureErrors(correlationId: string): void { // Log uncaught exceptions process.on('uncaughtException', (ex) => { this._logger.fatal(correlationId, ex, "Process is terminated"); process.exit(1); }); } private captureExit(correlationId: string): void { this._logger.info(correlationId, "Press Control-C to stop the microservice..."); // Activate graceful exit process.on('SIGINT', () => { process.exit(); }); // Gracefully shutdown process.on('exit', () => { this.close(correlationId); this._logger.info(correlationId, "Goodbye!"); }); } /** * Runs the container by instantiating and running components inside the container. * * It reads the container configuration, creates, configures, references and opens components. * On process exit it closes, unreferences and destroys components to gracefully shutdown. * * @param args command line arguments */ public run(args: string[]): void { if (this.showHelp(args)) { this.printHelp(); return; } let correlationId = this._info.name; let path = this.getConfigPath(args); let parameters = this.getParameters(args); this.readConfigFromFile(correlationId, path, parameters); this.captureErrors(correlationId); this.captureExit(correlationId); this.open(correlationId); } }