deepify
Version:
DEEP Development Tools
445 lines (351 loc) • 10.1 kB
JavaScript
/**
* 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;