1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | const { wrap } = require('underscore');
|
7 |
|
8 | const express = require('abacus-express');
|
9 | const eureka = require('abacus-eureka');
|
10 | const hystrix = require('abacus-hystrix');
|
11 | const oauth = require('abacus-oauth');
|
12 | const perf = require('abacus-perf');
|
13 | const metrics = require('abacus-metrics');
|
14 | const router = require('abacus-router');
|
15 | const vcapenv = require('abacus-vcapenv');
|
16 |
|
17 | const { OK: STATUS_OK, INTERNAL_SERVER_ERROR: STATUS_INTERNAL_SERVER_ERROR } = require('http-status-codes');
|
18 |
|
19 |
|
20 | const debug = require('abacus-debug')('abacus-webapp');
|
21 |
|
22 | const defaultSecurity = () => process.env.SECURED === 'true';
|
23 | const secured = () => process.env.HEALTHCHECK_SECURED === 'false' ? false : defaultSecurity();
|
24 |
|
25 | const healthCheckScopes = 'abacus.system.read';
|
26 | const metricsAuthorizationScopes = ['abacus.system.read'];
|
27 |
|
28 | const defaultHealthCheck = (req, res) => {
|
29 | debug(`Entering ${secured ? 'secured' : ''} healthcheck`);
|
30 | const h = perf.healthy();
|
31 | debug('Returning app health %s', h);
|
32 | res.status(h ? STATUS_OK : STATUS_INTERNAL_SERVER_ERROR).send({
|
33 | healthy: h
|
34 | });
|
35 | };
|
36 |
|
37 | const createMetricsRoute = () => {
|
38 | const route = router();
|
39 | if (secured())
|
40 | route.use(oauth.authorizer(process.env.JWTKEY, process.env.JWTALGO, metricsAuthorizationScopes));
|
41 | route.use(metrics.createMiddleware(metrics.defaultCollection));
|
42 | return route;
|
43 | };
|
44 |
|
45 | const appName = vcapenv.appname();
|
46 |
|
47 |
|
48 | const webapp = () => {
|
49 | debug('Setting up %s environment', appName);
|
50 | process.env.TZ = 'UTC';
|
51 | if (!process.env.VCAP_APPLICATION) {
|
52 | process.env.PORT = process.env.PORT || process.env.npm_package_config_port;
|
53 | process.env.APPS = 1;
|
54 | process.env.APP_NAME = appName;
|
55 | process.env.APP_INDEX = 0;
|
56 | process.env.INSTANCES = 1;
|
57 | process.env.INSTANCE_INDEX = 0;
|
58 | }
|
59 |
|
60 | debug('Creating %s', appName);
|
61 | const app = express();
|
62 | app.use(vcapenv.headers());
|
63 | app.use('/v1/metrics', createMetricsRoute());
|
64 |
|
65 | let healthCheckMiddlware = defaultHealthCheck;
|
66 |
|
67 | |
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | app.useHealthCheck = (middleware) => {
|
75 | if (middleware) healthCheckMiddlware = middleware;
|
76 | else healthCheckMiddlware = defaultHealthCheck;
|
77 | };
|
78 |
|
79 |
|
80 |
|
81 | app.listen = wrap(app.listen, (listen, opt, cb) => {
|
82 | if (secured()) {
|
83 | app.use(
|
84 | '/hystrix.stream',
|
85 | oauth.basicStrategy(process.env.API, hystrix.scopes, process.env.JWTKEY, process.env.JWTALGO)
|
86 | );
|
87 |
|
88 | app.use(
|
89 | '/healthcheck',
|
90 | oauth.basicStrategy(process.env.API, healthCheckScopes, process.env.JWTKEY, process.env.JWTALGO)
|
91 | );
|
92 | }
|
93 |
|
94 | app.use('/hystrix.stream', hystrix.stream());
|
95 | app.get('/healthcheck', healthCheckMiddlware);
|
96 |
|
97 |
|
98 | debug('Application %s listening', appName);
|
99 | const server = listen.call(app, opt, cb);
|
100 |
|
101 |
|
102 | if (eureka())
|
103 | eureka.register(eureka(), appName, vcapenv.iport() || server.address().port, vcapenv.iaddress(), (err, val) => {
|
104 | if (err) debug('Couldn\'t register app %s in Eureka registry, %o', appName, err);
|
105 | else debug('Registered app %s in Eureka registry', appName);
|
106 | });
|
107 |
|
108 | if (process.env.CONNECTION_TIMEOUT) {
|
109 | const connectionTimeout = parseInt(process.env.CONNECTION_TIMEOUT);
|
110 | debug('Setting %s connection timeout to %d', appName, connectionTimeout);
|
111 | server.setTimeout(connectionTimeout);
|
112 | }
|
113 |
|
114 | return server;
|
115 | });
|
116 |
|
117 | debug('%s started', appName);
|
118 | return app;
|
119 | };
|
120 |
|
121 | module.exports = webapp;
|