1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const events_1 = require("events");
|
4 | const instance_1 = require("./instance");
|
5 | const Logger_1 = require("./Logger");
|
6 | const LogSeverity_1 = require("./LogSeverity");
|
7 | const ApplicationEvent_1 = require("./ApplicationEvent");
|
8 | const Request_1 = require("./Request");
|
9 | const Response_1 = require("./Response");
|
10 | const ConfigLoader_1 = require("./ConfigLoader");
|
11 | const Commander = require("commander");
|
12 | const Express = require("express");
|
13 | const BodyParser = require("body-parser");
|
14 | const http = require("http");
|
15 | require('source-map-support').install();
|
16 | const DEFAULT_LOG_LEVEL = LogSeverity_1.LogSeverity.INFO | LogSeverity_1.LogSeverity.WARNING | LogSeverity_1.LogSeverity.ERROR | LogSeverity_1.LogSeverity.FATAL;
|
17 | class Application extends events_1.EventEmitter {
|
18 | constructor(name, configPath, logSeverity) {
|
19 | super();
|
20 | instance_1.setInstance(this);
|
21 | this._isTestEnvironment = false;
|
22 | this.$buildArgOptions();
|
23 | if (global.jasmine) {
|
24 | this._isTestEnvironment = true;
|
25 | }
|
26 | this._program.parse(process.argv);
|
27 | this.name = name;
|
28 | this.logger = this._createLogger();
|
29 | if (logSeverity) {
|
30 | this._logConfigDefaulting = false;
|
31 | this.getLogger().setLogLevel(logSeverity);
|
32 | }
|
33 | else {
|
34 | this._logConfigDefaulting = true;
|
35 | this.getLogger().setLogLevel(this._getDefaultLogLevel());
|
36 | }
|
37 | process.on('unhandledRejection', (error) => {
|
38 | this.getLogger().fatal(error);
|
39 | });
|
40 | this.configPath = configPath || process.cwd();
|
41 | this.getLogger().trace('Application is booting...');
|
42 | this.getLogger().trace('Loading Configuration...');
|
43 | this._load();
|
44 | }
|
45 | _load() {
|
46 | this.loadConfig(this.configPath).then((config) => {
|
47 | this.config = config;
|
48 | this.getLogger().trace('Configuration loaded.');
|
49 | this.emit(ApplicationEvent_1.ApplicationEvent.CONFIG_LOADED);
|
50 | this.onConfigLoad(this.config);
|
51 | return Promise.resolve();
|
52 | }).then(() => {
|
53 | if (this._logConfigDefaulting) {
|
54 | let logSeverity = this._parseLogLevelConfig(this.getConfig());
|
55 | this.logger.setLogLevel(logSeverity);
|
56 | }
|
57 | this.logger.loadFilters();
|
58 | this.getLogger().trace('Initializing DB...');
|
59 | return this.initDB(this.getConfig());
|
60 | }).then((db) => {
|
61 | if (db) {
|
62 | this.getLogger().trace('DB Initialized.');
|
63 | }
|
64 | else {
|
65 | this.getLogger().trace('DB is not initialized.');
|
66 | }
|
67 | this.db = db;
|
68 | return Promise.resolve();
|
69 | }).then(() => {
|
70 | this.getLogger().trace('Starting server...');
|
71 | this.server = Express();
|
72 | this.server.use(BodyParser.json({
|
73 | type: 'application/json',
|
74 | limit: this.getRequestSizeLimit()
|
75 | }));
|
76 | this.server.use(BodyParser.text({
|
77 | type: 'text/*',
|
78 | limit: this.getRequestSizeLimit()
|
79 | }));
|
80 | return Promise.resolve();
|
81 | }).then(() => {
|
82 | this.getLogger().trace('Attaching handlers...');
|
83 | return this.attachHandlers();
|
84 | }).then(() => {
|
85 | this.onBeforeReady();
|
86 | let bindingIP = this.getConfig().binding_ip;
|
87 | let port = this.getConfig().port;
|
88 | if (bindingIP !== null && bindingIP !== 'null') {
|
89 | if (this.shouldListen()) {
|
90 | this.socket = http.createServer(this.server);
|
91 | this.socket.listen(port, bindingIP, () => {
|
92 | this.getLogger().trace(`Server started on ${bindingIP}:${this.getPort()}`);
|
93 | });
|
94 | }
|
95 | else {
|
96 | this.getLogger().trace('Server did not bind because shouldListen() returned false.');
|
97 | }
|
98 | }
|
99 | else {
|
100 | this.getLogger().info(`Server does not have a bounding IP set. The server will not be listening for connections.`);
|
101 | }
|
102 | this.onReady();
|
103 | this.emit('ready');
|
104 | }).catch((error) => {
|
105 | this.getLogger().fatal(error);
|
106 | });
|
107 | }
|
108 | getPort() {
|
109 | let port = null;
|
110 | if (this.socket && this.socket.listening) {
|
111 | let address = this.socket.address();
|
112 | if (typeof address !== 'string') {
|
113 | port = address.port;
|
114 | }
|
115 | }
|
116 | return port;
|
117 | }
|
118 | $buildArgOptions() {
|
119 | this._program = Commander;
|
120 | let pkg = require('../package.json');
|
121 | this._program.version(pkg.version, '-v, --version');
|
122 | this._program.option('--port <port>', 'The running port to consume');
|
123 | this._program.option('--binding <ip>', 'The binding IP to listen on');
|
124 | this._program.option('--authentication_header', 'The header name of the authentication token');
|
125 | this._buildArgOptions(this._program);
|
126 | }
|
127 | _buildArgOptions(program) { }
|
128 | getProgram() {
|
129 | return this._program;
|
130 | }
|
131 | getRequestSizeLimit() {
|
132 | return this.getConfig().request_size_limit;
|
133 | }
|
134 | attachHandler(path, HandlerClass) {
|
135 | let handler = new HandlerClass(this);
|
136 | this.server.get(path, (request, response) => {
|
137 | let r = new Request_1.Request(request);
|
138 | handler.get(r, new Response_1.Response(response, r.getURL()));
|
139 | });
|
140 | this.server.post(path, (request, response) => {
|
141 | let r = new Request_1.Request(request);
|
142 | handler.post(r, new Response_1.Response(response, r.getURL()));
|
143 | });
|
144 | this.server.put(path, (request, response) => {
|
145 | let r = new Request_1.Request(request);
|
146 | handler.put(r, new Response_1.Response(response, r.getURL()));
|
147 | });
|
148 | this.server.delete(path, (request, response) => {
|
149 | let r = new Request_1.Request(request);
|
150 | handler.delete(r, new Response_1.Response(response, r.getURL()));
|
151 | });
|
152 | }
|
153 | close() {
|
154 | return new Promise((resolve, reject) => {
|
155 | if (this.socket && this.socket.listening) {
|
156 | this.socket.close(() => {
|
157 | resolve();
|
158 | });
|
159 | }
|
160 | else {
|
161 | resolve();
|
162 | }
|
163 | });
|
164 | }
|
165 | loadConfig(path) {
|
166 | return new Promise((resolve, reject) => {
|
167 | ConfigLoader_1.ConfigLoader.load(path).then((config) => {
|
168 | resolve(config);
|
169 | }).catch((exitCode) => {
|
170 | process.exit(exitCode);
|
171 | });
|
172 | });
|
173 | }
|
174 | getName() {
|
175 | return this.name;
|
176 | }
|
177 | setLogger(logger) {
|
178 | this.logger = logger;
|
179 | }
|
180 | getLogger() {
|
181 | return this.logger;
|
182 | }
|
183 | getConfig() {
|
184 | return this.config;
|
185 | }
|
186 | shouldListen() {
|
187 | return true;
|
188 | }
|
189 | onConfigLoad(config) { }
|
190 | setTokenManager(tokenManager) {
|
191 | this.tokenManager = tokenManager;
|
192 | }
|
193 | getTokenManager() {
|
194 | return this.tokenManager;
|
195 | }
|
196 | getDB() {
|
197 | return this.db;
|
198 | }
|
199 | getCmdLineArgs() {
|
200 | let program = this._program;
|
201 | let o = {};
|
202 | if (!program) {
|
203 | return o;
|
204 | }
|
205 | if (program.binding !== undefined) {
|
206 | o.binding_ip = program.binding;
|
207 | }
|
208 | if (program.port !== undefined) {
|
209 | o.port = program.port;
|
210 | }
|
211 | if (program.authenticationHeader !== undefined) {
|
212 | o.authentication_header = program.authenticationHeader;
|
213 | }
|
214 | return o;
|
215 | }
|
216 | initDB(config) {
|
217 | return Promise.resolve(null);
|
218 | }
|
219 | _createLogger() {
|
220 | return new Logger_1.Logger(this.getName());
|
221 | }
|
222 | _getDefaultLogLevel() {
|
223 | return DEFAULT_LOG_LEVEL;
|
224 | }
|
225 | _parseLogLevelConfig(config) {
|
226 | let llConfig = config.log_level;
|
227 | let severity = null;
|
228 | if (!llConfig) {
|
229 | return null;
|
230 | }
|
231 | llConfig = llConfig.toLowerCase().trim();
|
232 | if (llConfig.indexOf('all') > -1) {
|
233 | return LogSeverity_1.LogSeverity.ALL;
|
234 | }
|
235 | if (llConfig.indexOf('|') === -1) {
|
236 | severity = this._llStrToSeverity(llConfig);
|
237 | }
|
238 | else {
|
239 | let llParts = llConfig.split('|');
|
240 | for (let i = 0; i < llParts.length; i++) {
|
241 | let llPart = llParts[i];
|
242 | llPart = llPart.trim();
|
243 | if (llPart === '') {
|
244 | continue;
|
245 | }
|
246 | let llSev = this._llStrToSeverity(llPart);
|
247 | if (!llSev) {
|
248 | continue;
|
249 | }
|
250 | if (!severity) {
|
251 | severity = llSev;
|
252 | }
|
253 | else {
|
254 | severity = severity | llSev;
|
255 | }
|
256 | }
|
257 | }
|
258 | return severity;
|
259 | }
|
260 | _llStrToSeverity(ll) {
|
261 | switch (ll) {
|
262 | case 'all':
|
263 | return LogSeverity_1.LogSeverity.ALL;
|
264 | case 'trace':
|
265 | return LogSeverity_1.LogSeverity.TRACE;
|
266 | case 'debug':
|
267 | return LogSeverity_1.LogSeverity.DEBUG;
|
268 | case 'info':
|
269 | return LogSeverity_1.LogSeverity.INFO;
|
270 | case 'warning':
|
271 | return LogSeverity_1.LogSeverity.WARNING;
|
272 | case 'error':
|
273 | return LogSeverity_1.LogSeverity.ERROR;
|
274 | case 'fatal':
|
275 | return LogSeverity_1.LogSeverity.FATAL;
|
276 | default:
|
277 | return null;
|
278 | }
|
279 | }
|
280 | onBeforeReady() { }
|
281 | onReady() { }
|
282 | }
|
283 | exports.Application = Application;
|
284 |
|
\ | No newline at end of file |