UNPKG

deepify

Version:
445 lines (351 loc) 10.1 kB
/** * Created by AlexanderC on 8/10/15. */ /* eslint callback-return: 0 */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Instance = undefined; var _PropertyObjectRequiredException = require('./Exception/PropertyObjectRequiredException'); var _http = require('http'); var _http2 = _interopRequireDefault(_http); var _https = require('https'); var _https2 = _interopRequireDefault(_https); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _url = require('url'); var _url2 = _interopRequireDefault(_url); var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _FailedToStartServerException = require('./Exception/FailedToStartServerException'); var _deepPackageManager = require('deep-package-manager'); var _deepDb = require('deep-db'); var _deepDb2 = _interopRequireDefault(_deepDb); var _deepFs = require('deep-fs'); var _deepFs2 = _interopRequireDefault(_deepFs); var _Hook = require('./Hook'); var _ResponseEvent = require('../Helpers/ResponseEvent'); var _AsyncConfig = require('../Helpers/AsyncConfig'); var _RequestListener = require('./Listener/RequestListener'); var _ConfigListener = require('./Listener/ConfigListener'); var _AsyncConfigListener = require('./Listener/AsyncConfigListener'); var _FileListener = require('./Listener/FileListener'); var _LambdaListener = require('./Listener/LambdaListener'); var _IndexListener = require('./Listener/IndexListener'); var _Server = require('../Elasticsearch/Server'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class Instance { /** * @param {Property} property */ constructor(property) { if (!(property instanceof _deepPackageManager.Property_Instance)) { throw new _PropertyObjectRequiredException.PropertyObjectRequiredException(); } this._logger = (...args) => { console.log(...args); }; this._property = property; this._server = null; this._fs = null; this._es = new _Server.Server(property); this._host = null; this._localId = 0; this._profiling = false; this._defaultFrontendConfig = {}; this._defaultLambdasConfig = {}; this._rootMicroservice = {}; this._microservices = {}; this._events = {}; this._events[Instance.RESPONSE_EVENT] = []; this._setup(); this._asyncConfig = new _AsyncConfig.AsyncConfig(this); this._listener = new _RequestListener.RequestListener(this); this._listener.register(new _ConfigListener.ConfigListener(), 0).register(new _AsyncConfigListener.AsyncConfigListener(this), 1).register(new _LambdaListener.LambdaListener(this), 2).register(new _IndexListener.IndexListener(this), 3).register(new _FileListener.FileListener(this), 4); } /** * @returns {DeepFS} */ get fs() { return this._fs; } /** * @returns {ES} */ get es() { return this._es; } /** * @returns {AsyncConfig} */ get asyncConfig() { return this._asyncConfig; } /** * @returns {String} */ get host() { return this._host; } /** * @returns {Object} */ get defaultLambdasConfig() { return this._defaultLambdasConfig; } /** * @returns {Object} */ get defaultFrontendConfig() { return this._defaultFrontendConfig; } /** * @returns {Listener} */ get listener() { return this._listener; } /** * @returns {Object} */ get microservices() { return this._microservices; } /** * @returns {Object} */ get rootMicroservice() { return this._rootMicroservice; } /** * @returns {Boolean} */ get profiling() { return this._profiling; } /** * @param {Boolean} state */ set profiling(state) { this._profiling = state; } /** * @returns {Function} */ get logger() { return this._logger; } /** * @param {Function} logger */ set logger(logger) { this._logger = logger; } /** * @private */ _setup() { this._defaultLambdasConfig = this._property.fakeBuild(); let microservices = this._property.microservices; for (let microservice of microservices) { if (microservice.isRoot) { this._rootMicroservice = this._buildMicroservice(microservice); this._rootMicroservice.isRoot = true; } else { this._microservices[microservice.identifier] = this._buildMicroservice(microservice); } } this._defaultFrontendConfig = _deepPackageManager.Property_Frontend.createConfig(this._property.config, true); } /** * @param {Microservice} microservice * @returns {Object} * @private */ _buildMicroservice(microservice) { let build = { identifier: microservice.identifier, path: microservice.basePath, frontend: microservice.autoload.frontend, lambdas: {} }; for (let action of microservice.resources.actions) { if (action.type === _deepPackageManager.Microservice_Metadata_Action.LAMBDA) { build.lambdas[action.identifier] = { path: _path2.default.join(microservice.autoload.backend, action.source, 'bootstrap.js'), methods: action.methods }; } } return build; } /** * @returns {Property} */ get property() { return this._property; } /** * @returns {Http.Server|Https.Server} */ get nativeServer() { return this._server; } /** * @returns {Boolean} */ get running() { return !!this._server; } /** * @param {String} mainPath * @param {String} configFile * @returns {Instance} */ static create(mainPath, configFile = _deepPackageManager.Property_Config.DEFAULT_FILENAME) { return new Instance(new _deepPackageManager.Property_Instance(mainPath, configFile)); } /** * @returns {Object} * @private */ get _kernelMock() { let lambdasArns = Object.keys(this._defaultLambdasConfig); let kernel = { config: { buckets: { private: { name: '' }, public: { name: '' }, temp: { name: '' } } }, microservice: () => { // do not return a real microservice identifier return { identifier: '' }; } }; if (lambdasArns.length > 0) { kernel.config = this._defaultLambdasConfig[lambdasArns[0]]; } return kernel; } /** * @param {Number} port * @param {String} dbServer * @param {Function} callback * @param {Boolean} isSecured * @returns {Instance} */ listen(port = 8080, dbServer = null, callback = () => {}, isSecured = false) { let hook = new _Hook.Hook(this); hook.runBefore(() => { this._log('Booting local FS'); this._es.launchInstances(); this._fs = new _deepFs2.default(); this._fs.localBackend = true; this._fs.boot(this._kernelMock, () => { this._log('Linking custom validation schemas'); _deepPackageManager.Property_Frontend.dumpValidationSchemas(this._property.config, this._fs.public._rootFolder, true); this._log(`Creating server on port ${port}`); if (isSecured) { // @todo abstract this let sslKeysDir = _path2.default.join(__dirname, '..', '..', 'assets'); let options = { key: _fs2.default.readFileSync(_path2.default.join(sslKeysDir, 'localhost.key')), cert: _fs2.default.readFileSync(_path2.default.join(sslKeysDir, 'localhost.cert')) }; this._server = _https2.default.createServer(options, (...args) => { this._handler(...args); }); } else { this._server = _http2.default.createServer((...args) => { this._handler(...args); }); } var localDbInstance = null; this._server.listen(port, error => { if (error) { throw new _FailedToStartServerException.FailedToStartServerException(port, error); } this._host = `http${isSecured ? 's' : ''}://localhost:${port}`; this._log('HTTP Server is up and running!'); if (!dbServer) { hook.runAfter(() => { callback(this); }); return; } this._log(`Creating local DynamoDB instance on port ${_deepDb2.default.LOCAL_DB_PORT}`); localDbInstance = _deepDb2.default.startLocalDynamoDBServer(error => { if (error) { throw new _FailedToStartServerException.FailedToStartServerException(port, error); } this._log(`You can access DynamoDB Console via http://localhost:${_deepDb2.default.LOCAL_DB_PORT}/shell`); hook.runAfter(() => { callback(this); }); }, dbServer); }); // @todo: move it in destructor? process.on('exit', () => { this.stop(() => { if (localDbInstance) { localDbInstance.stop(() => { process.exit(0); }); } else { process.exit(0); } }); }); }); }); return this; } /** * @param {Function} callback * @returns {Instance} */ stop(callback = () => {}) { if (this.running) { this._server.close(callback); } else { callback(); } return this; } /** * @returns {Number} */ get localId() { return this._localId++; } /** * @param {Http.IncomingMessage|Https.IncomingMessage} request * @param {Http.ServerResponse|Https.ServerResponse} response * @private */ _handler(request, response) { let urlParts = _url2.default.parse(request.url); let uri = urlParts.pathname; this._log(`Request ${request.url} -> ${uri}`); this.listener.dispatchEvent(new _ResponseEvent.ResponseEvent(request, response)); } /** * @param {String} args * @private */ _log(...args) { this._logger(...args); } } exports.Instance = Instance;