-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathapp.js
More file actions
125 lines (108 loc) · 3.24 KB
/
Copy pathapp.js
File metadata and controls
125 lines (108 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require('path');
const cookieParser = require('cookie-parser');
const passport = require('./middleware/passport');
var useragent = require('express-useragent');
const createNewLogger = require('./log-service');
const webApp = require('./routes/webApp');
const apiRouter = require('./routes/api');
const dataRetrievalRoutes = require('./routes/dataRetrieval');
const ApiCallDetails = require('./models/ApiCallDetail');
const { v4: uuidv4 } = require('uuid');
const { runStartupTasks } = require('./startup');
const env = require('./config/environment');
const log = createNewLogger()
.setModule('app.js')
.addContext(['node_version', process.version]);
log.info('starting app', {
DEBUG_USAGE: process.env.DEBUG_USAGE,
DEBUG_USAGE_THROTTLE_MS: process.env.DEBUG_USAGE_THROTTLE_MS,
CLUSTER_CHUNK_MAX_ROWS: process.env.CLUSTER_CHUNK_MAX_ROWS,
});
const app = express();
const port = process.env.PORT || 8080;
process.on('warning', ({ name, message, stack }) => {
log.warn(message, { name, stack });
});
process.on('uncaughtException', (err) => {
log.error('uncaught exception', {
error: err,
message: err.message,
stack: err.stack,
});
process.exit(1);
});
process.on('unhandledRejection', (reason) => {
log.error('unhandled promise rejection', {
reason: reason,
message: reason && reason.message,
stack: reason && reason.stack,
});
process.exit(1);
});
// Middleware
app.use(
cors({
origin: true,
credentials: true,
exposedHeaders: [
'X-CMAP-Request-Id',
'X-Catalog-Checksum',
'X-Catalog-Schema-Hash',
'X-Catalog-Dataset-Count',
'X-Catalog-Generated-At',
],
}),
);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize());
app.use(useragent.express());
// Create a request id
app.use((req, res, next) => {
let reqId = uuidv4();
req.requestId = reqId;
res.set('X-CMAP-Request-Id', reqId);
next();
});
// Attaching call details to request object for usage tracking
app.use((req, res, next) => {
req.cmapApiCallDetails = new ApiCallDetails(req);
req.cmapApiCallDetails.checkIp();
next();
});
// Execute startup tasks after Express setup but before routes
runStartupTasks().catch((error) => {
log.error('Startup tasks failed unexpectedly', { error });
});
// Routes - DEPRECATED
app.use(
'/dataretrieval',
passport.authenticate(['headerapikey', 'jwt'], { session: false }),
dataRetrievalRoutes,
);
// API
app.use('/api', apiRouter);
// Web App
app.use(webApp);
// Usage metrics logging
app.use((req, res, next) => {
// this will execute if neither the api nor webApp have already saved call details
req.cmapApiCallDetails.save(res, { caller: 'app' });
next();
});
// start web server
const server = app.listen(port, () => {
log.info('api web server started', {
port,
nodeEnv: env.NODE_ENV,
});
});
// Extend default 2-minute timeout for long-running requests (bulk downloads, row counts)
// Must be >= ELB idle timeout (3600s) to avoid premature socket closure
server.timeout = 3600000;