'use strict'; const assert = require('assert'); const commander = require('commander'); const _ = require('lodash'); const EventEmitter = require('events'); const util = require('util'); const bootstrap = require('./lib/bootstrap'); const loggerUtil = require('./lib/utils/logger'); const validators = require('./lib/configuration/validators'); const appConfig = require('./lib/configuration/app-config'); const envConfig = require('./lib/configuration/env-config'); const MiddlewareList = require('./lib/extensions/MiddlewareList'); const serverLib = require('./lib/server'); const optionalCallback = require('./lib/utils/callback'); const uaaUtils = require('./lib/utils/uaa-utils'); const dynamicRoutingUtils = require('./lib/utils/dynamic-routing-utils'); module.exports = Approuter; function Approuter() { assert(arguments.length === 0, 'Constructor takes no arguments'); if (!(this instanceof Approuter)) { return new Approuter(); } EventEmitter.call(this); this.cmdParser = new commander.Command() .option('-w, --workingDir ', 'The working directory containting the resources folder and xs-app.json file') .option('-p, --port ', 'The port of the approuter'); this.first = new MiddlewareList(); this.beforeRequestHandler = new MiddlewareList(); this.beforeErrorHandler = new MiddlewareList(); } util.inherits(Approuter, EventEmitter); Approuter.prototype.start = function (options, callback) { let self = this; if (dynamicRoutingUtils.isDynamicRouting()) { self.first.use(dynamicRoutingUtils.initialize(self)); if (options) { delete options.port; options.getRouterConfig = dynamicRoutingUtils.getRouterConfig; } else { options = {'getRouterConfig': dynamicRoutingUtils.getRouterConfig}; } } if (options) { validators.validateApprouterStartOptions(options); options = _.cloneDeep(options); } else { options = {}; } callback = optionalCallback(callback); if (this.cmdParser) { this.cmdParser.parse(process.argv); options = _.defaults(options, this.cmdParser); } addImplicitExtension(this, options); let logger = loggerUtil.getLogger('/approuter'); logger.info('Application router version %s', require('./package.json').version); let app = bootstrap(options); app.logger = logger; app.approuter = this; this._app = app; loggerUtil.getAuditLogger(function(err, auditLogger){ if (err) { throw err; } app.auditLogger = auditLogger; serverLib.start(app, function (err, server) { self._server = server; callback(err); }); }); }; Approuter.prototype.close = function (callback) { if (this._server) { clearInterval(this._app._store.memoryStore.sessionChecker); this._server.close(callback); } else { process.nextTick(callback); } }; Approuter.prototype.resolveUaaConfig = uaaUtils.resolveUaaConfig; Approuter.prototype.getRemoteConfigurationOptions = dynamicRoutingUtils.getRemoteConfigurationOptions; Approuter.prototype.createRouterConfig = function (options, callback) { options = _.cloneDeep(options); // avoid side effects in case of modifications let error; let routerConfig; try { assert(this._app, 'Call Approuter.start before Approuter.createRouterConfig'); routerConfig = this._app.get('mainRouterConfig'); let xsappname = options.xsappname || routerConfig.uaaConfig.options.xsappname; let customDestinations = (options.destinations) ? envConfig.loadDestinations(options.destinations) : routerConfig.destinations; let customAppConfig = appConfig.loadConfiguration(routerConfig.workingDir, options.xsappConfig, customDestinations, xsappname); customAppConfig.logout = _.extend({}, routerConfig.appConfig.logout, _.pick(customAppConfig.logout, 'logoutPage', 'logoutEndpoint', 'logoutMethod', 'csrfProtection')); routerConfig = _.defaults({ appConfig: customAppConfig, destinations: customDestinations }, routerConfig); } catch (err) { error = err; } callback(error, routerConfig); }; Approuter.prototype.getSessionStore = function getSessionStore() { let memoryStore = this._app.get('memoryStore'); return Object.create(memoryStore, { set: { value: function(sessionId, sessionString, timeout, callback) { let diff = timeout - Date.now(); memoryStore.set(sessionId, JSON.parse(sessionString), callback); memoryStore.sessionTimers[sessionId] = Math.floor(diff / 10000); // tens of seconds } } }); }; function addImplicitExtension(ar, options) { let ext = { insertMiddleware: { first: ar.first._middleware, beforeRequestHandler: ar.beforeRequestHandler._middleware, beforeErrorHandler: ar.beforeErrorHandler._middleware } }; options.extensions = options.extensions || []; options.extensions.unshift(ext); } if (require.main === module) { let ar = new Approuter(); ar.start(); }