@mimik/init 3.9.4 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
- <a name="module_ini"></a>
1
+ <a name="module_init"></a>
2
2
 
3
- ## ini
3
+ ## init
4
4
  **Example**
5
5
  ```js
6
6
  const init = require('@mimik/init');
7
7
 
8
8
  init(config, dbValidate, { postOps: [suscribe] }).then(result => config = result);
9
9
  ```
10
- <a name="exp_module_ini--module.exports"></a>
10
+ <a name="exp_module_init--module.exports"></a>
11
11
 
12
12
  ### module.exports(app, rootDir, config, validates, cluster, options) ⇒ <code>object</code> ⏏
13
13
  Init process for a micro-service.
package/index.js CHANGED
@@ -1,31 +1,31 @@
1
- const swaggerTools = require('swagger-tools');
2
- const http = require('http');
3
1
  const cors = require('cors');
4
- const path = require('path');
2
+ const http = require('http');
3
+ const pathLib = require('path');
5
4
  const Promise = require('bluebird');
6
5
  const helmet = require('helmet');
7
6
 
8
7
  const logger = require('@mimik/sumologic-winston-logger');
9
- const swagger = require('@mimik/swagger-helper');
10
- const oauthHelper = require('@mimik/oauth-helper');
11
8
  const { startupHealthInfo } = require('@mimik/healthcheck');
12
- const { healthInfo } = require('@mimik/systeminfo');
13
9
  const { getPublic } = require('@mimik/public-helper');
14
10
  const { getCorrelationId } = require('@mimik/request-helper');
11
+ const { apiSetup, setupServerFiles } = require('@mimik/api-helper');
12
+
15
13
  const { extractLogs } = require('./lib/logs');
16
14
  const { sigProcess } = require('./lib/exit');
17
- const { APIRequestMetrics, startHrTimeSet } = require('./lib/metrics');
18
- const { HEALTHCHECK_ROUTE, METRICS_ROUTE } = require('./lib/common');
19
-
20
- const SIGINT = 'SIGINT';
21
- const SIGTERM = 'SIGTERM';
22
- const LOCAL = 'local';
23
- const SET_ON = 'on';
24
- const CONTENT_TYPE = 'Content-Type';
25
- const JSON_CONTENT = 'application/json';
15
+ const { startHrTimeSet } = require('./lib/metrics');
16
+ const { healthCheckRoute, metricsRoute } = require('./lib/route');
17
+ const {
18
+ HEALTHCHECK_ROUTE,
19
+ METRICS_ROUTE,
20
+ SIGINT,
21
+ SIGTERM,
22
+ LOCAL,
23
+ SET_ON,
24
+ BUILD_FILENAME,
25
+ } = require('./lib/common');
26
26
 
27
27
  /**
28
- * @module ini
28
+ * @module init
29
29
  * @example
30
30
  * const init = require('@mimik/init');
31
31
  *
@@ -72,19 +72,41 @@ module.exports = (app, rootDir, config, validates, cluster, options) => {
72
72
 
73
73
  if (!config) return fatalError(new Error('config is required'));
74
74
  const { serverSettings, dependencies } = config;
75
+ const updateOptions = (origOpts) => {
76
+ const apiInfo = {
77
+ provider: serverSettings.swaggerFile.provider,
78
+ apiApikey: serverSettings.apiApiKey,
79
+ apiBasicAuth: serverSettings.apiBasicAuth,
80
+ };
81
+ let opts = origOpts;
82
+
83
+ if (opts) opts.apiInfo = apiInfo;
84
+ else opts = { apiInfo };
85
+ return opts;
86
+ };
75
87
  const serverPort = serverSettings.port;
76
88
  const correlationIdStart = getCorrelationId(`system-start:${serverSettings.id}`);
77
89
 
78
90
  if (!cluster) return fatalError(new Error('cluster lib required'), correlationIdStart);
79
91
  if (!app) return fatalError(new Error('app is required'), correlationIdStart);
80
92
  const { register, unRegister } = cluster;
81
- const oauth = oauthHelper(config);
82
93
  const server = http.createServer(app);
83
-
84
- let swaggerFilename = serverSettings.api;
85
- let extractName = null;
94
+ const controllersDirectory = pathLib.join(rootDir, './controllers');
95
+ const buildDirectory = pathLib.join(rootDir, './build');
96
+ const buildRequire = pathLib.join(buildDirectory, BUILD_FILENAME);
97
+ const extractName = options ? options.extractName : null;
98
+ const metrics = options ? options.metrics : null;
99
+ let apiFilename = serverSettings.api;
86
100
  let registration = false;
87
101
 
102
+ if ((config.nodeEnvironment.toLowerCase() !== LOCAL) || (config.registration.set === SET_ON)) { registration = true; }
103
+ else logger.warn('registration disabled: cluster will not work', correlationIdStart);
104
+ if (extractName) {
105
+ if (!dependencies || !dependencies.mLG) return fatalError(new Error('requesting extraction without mLG configuration'), correlationIdStart);
106
+ dependencies.mLG.extractName = extractName;
107
+ }
108
+ if (metrics && !metrics.register) return fatalError(new Error('register is required in metrics'), correlationIdStart);
109
+
88
110
  process.on(SIGINT, () => {
89
111
  sigProcess(SIGINT, registration, options, config, server, unRegister, getCorrelationId(`system-shutdown(${SIGINT}):${serverSettings.id}`));
90
112
  });
@@ -100,78 +122,22 @@ module.exports = (app, rootDir, config, validates, cluster, options) => {
100
122
  },
101
123
  }));
102
124
  app.use(cors({ origin: '*' }));
103
- app.use(HEALTHCHECK_ROUTE, (req, res) => {
104
- res.setHeader(CONTENT_TYPE, JSON_CONTENT);
105
- res.end(JSON.stringify(healthInfo(), null, 2));
106
- });
107
- if (options.metrics && options.metrics.register) {
108
- app.use(METRICS_ROUTE, (req, res) => options.metrics.register.metrics()
109
- .then((result) => {
110
- res.setHeader(CONTENT_TYPE, options.metrics.register.contentType);
111
- res.end(result);
112
- })
113
- .catch((err) => {
114
- res.setHeader(CONTENT_TYPE, JSON_CONTENT);
115
- const errResponse = {
116
- statusCode: 500,
117
- title: http.STATUS_CODES[500],
118
- message: err.message,
119
- };
120
- res.end(JSON.stringify(errResponse), null, 2);
121
- }));
125
+ app.get(HEALTHCHECK_ROUTE, healthCheckRoute());
126
+ if (metrics) {
127
+ app.get(METRICS_ROUTE, metricsRoute(options));
128
+ app.use(startHrTimeSet(metrics.APIRequestDuration));
122
129
  }
123
- if (options && options.extractName) {
124
- ({ extractName } = options);
125
- if (!dependencies || !dependencies.mLG) {
126
- logger.warn('requesting extraction without mLG configuration', { extractName }, correlationIdStart);
127
- }
128
- else {
129
- dependencies.mLG.extractName = extractName;
130
- }
131
- }
132
- if (swaggerFilename[0] !== '/') swaggerFilename = path.join(rootDir, swaggerFilename);
133
- logger.debug('location of the swagger file', { swaggerFilename }, correlationIdStart);
134
- return swagger.getAPIFile(swaggerFilename, correlationIdStart, config.apiBasicAuth, options)
135
- .then((swaggerJson) => swaggerTools.initializeMiddleware(swaggerJson, (middleware) => {
136
- serverSettings.basePath = swaggerJson.basePath;
137
- app.use(startHrTimeSet());
138
- app.use(middleware.swaggerMetadata());
139
- if (options && options.metrics) {
140
- app.use(APIRequestMetrics(options.metrics.APIRequestDuration, serverSettings.basePath));
141
- }
142
- app.use(middleware.swaggerValidator());
143
- if ((config.nodeEnvironment && config.nodeEnvironment.toLowerCase() !== LOCAL) || (serverSettings.securitySet === SET_ON)) {
144
- const securityOptions = {
145
- AdminSecurity: oauth.apiTokenAdminSecurityHelper,
146
- SystemSecurity: oauth.apiTokenSecurityHelper,
147
- UserSecurity: oauth.apiTokenSecurityHelper,
148
- APIKeySecurity: oauth.apiKeySecurityHelper,
149
- };
130
+ if (extractName) { app.use(extractLogs(config, extractName, options)); }
131
+ if (apiFilename[0] !== '/') apiFilename = pathLib.join(rootDir, apiFilename);
132
+ logger.debug('location of the api file', { apiFilename }, correlationIdStart);
133
+ return setupServerFiles(apiFilename, controllersDirectory, buildDirectory, correlationIdStart, updateOptions(options))
134
+ .then((setupResult) => {
135
+ serverSettings.basePath = setupResult.apiDefinition.servers[0].url; // need to address that later
136
+ // eslint-disable-next-line import/no-dynamic-require,global-require
137
+ const registeredOperations = require(buildRequire);
138
+ const api = apiSetup(setupResult, registeredOperations, options?.secOptions, options?.formats, config, correlationIdStart);
150
139
 
151
- if (options && options.secOptions) {
152
- Object.keys(options.secOptions).forEach((key) => {
153
- securityOptions[key] = options.secOptions[key];
154
- });
155
- }
156
- app.use(middleware.swaggerSecurity(securityOptions));
157
- }
158
- else logger.warn('security disabled: tokens will not be used and /me and /onbehalf will not work', correlationIdStart);
159
- if ((config.nodeEnvironment && config.nodeEnvironment.toLowerCase() !== LOCAL) || (config.registration.set === SET_ON)) {
160
- registration = true;
161
- }
162
- else logger.warn('registration disabled: cluster will not work', correlationIdStart);
163
- if (extractName) {
164
- app.use(extractLogs(config, extractName, options));
165
- }
166
- app.use(middleware.swaggerRouter({
167
- useStubs: config.nodeEnvironment === LOCAL,
168
- controllers: `${rootDir}/controllers`,
169
- }));
170
- app.use(middleware.swaggerUi());
171
- app.use(swagger.sendError);
172
- if (serverSettings.interceptError === SET_ON) {
173
- app.use(swagger.interceptError);
174
- }
140
+ app.use((req, res) => api.handleRequest(req, req, res));
175
141
  return Promise.each(validates, (validate) => validate())
176
142
  .then(() => getPublic(config.locationProvider, config.cloudProvider, correlationIdStart, options).then((publicConfig) => {
177
143
  logger.info('public environment', { status: publicConfig.status }, correlationIdStart);
@@ -189,8 +155,8 @@ module.exports = (app, rootDir, config, validates, cluster, options) => {
189
155
  if (registration) register(correlationIdStart);
190
156
  if (options && options.postOps) options.postOps.forEach((ops) => ops(correlationIdStart, config, server));
191
157
  });
192
- })
193
- .catch((error) => fatalError(error, correlationIdStart));
194
- }))
158
+ });
159
+ })
160
+ .catch((error) => fatalError(error, correlationIdStart))
195
161
  .then(() => ({ config }));
196
162
  };
package/lib/common.js CHANGED
@@ -2,8 +2,26 @@ const METRICS_ROUTE = '/metrics';
2
2
  const HEALTHCHECK_ROUTE = '/healthcheck';
3
3
  const OUT_OF_SPEC_ROUTE = 'outOfSpecificationRoute';
4
4
 
5
+ const CONTENT_TYPE = 'Content-Type';
6
+ const JSON_CONTENT = 'application/json';
7
+
8
+ const SIGINT = 'SIGINT';
9
+ const SIGTERM = 'SIGTERM';
10
+
11
+ const LOCAL = 'local';
12
+ const SET_ON = 'on';
13
+
14
+ const BUILD_FILENAME = 'register';
15
+
5
16
  module.exports = {
6
17
  METRICS_ROUTE,
7
18
  HEALTHCHECK_ROUTE,
8
19
  OUT_OF_SPEC_ROUTE,
20
+ CONTENT_TYPE,
21
+ JSON_CONTENT,
22
+ SIGINT,
23
+ SIGTERM,
24
+ LOCAL,
25
+ SET_ON,
26
+ BUILD_FILENAME,
9
27
  };
package/lib/metrics.js CHANGED
@@ -1,31 +1,8 @@
1
- const { HEALTHCHECK_ROUTE, METRICS_ROUTE, OUT_OF_SPEC_ROUTE } = require('./common');
2
-
3
- const APIRequestMetrics = (APIRequestDuration, basePath) => (req, res, next) => {
4
- const { swagger } = req;
5
- let apiPath = req.originalUrl;
6
-
7
- if (swagger) apiPath = swagger.apiPath;
8
- const startHrTime = req.metrics ? req.metrics.startHrTime : process.hrtime();
9
-
10
- res.on('finish', () => {
11
- if (apiPath !== METRICS_ROUTE && apiPath !== HEALTHCHECK_ROUTE) {
12
- const elapsedHrTime = process.hrtime(startHrTime);
13
- const elapsedTimeInMs = elapsedHrTime[0] * 1000 + elapsedHrTime[1] / 1e6;
14
-
15
- APIRequestDuration
16
- .labels(req.method, swagger ? `${basePath}${apiPath}` : OUT_OF_SPEC_ROUTE, req.originalUrl.includes('?'), res.statusCode)
17
- .observe(elapsedTimeInMs);
18
- }
19
- });
20
- next();
21
- };
22
-
23
- const startHrTimeSet = () => (req, res, next) => {
24
- req.metrics = { startHrTime: process.hrtime() };
1
+ const startHrTimeSet = (APIRequestDuration) => (req, res, next) => {
2
+ req.metrics = { startHrTime: process.hrtime(), APIRequestDuration };
25
3
  next();
26
4
  };
27
5
 
28
6
  module.exports = {
29
7
  startHrTimeSet,
30
- APIRequestMetrics,
31
8
  };
package/lib/route.js ADDED
@@ -0,0 +1,31 @@
1
+ const http = require('http');
2
+
3
+ const { healthInfo } = require('@mimik/systeminfo');
4
+
5
+ const { CONTENT_TYPE, JSON_CONTENT } = require('./common');
6
+
7
+ const healthCheckRoute = () => (req, res) => {
8
+ res.setHeader(CONTENT_TYPE, JSON_CONTENT);
9
+ res.end(JSON.stringify(healthInfo(), null, 2));
10
+ };
11
+
12
+ const metricsRoute = (options) => (req, res) => options.metrics.register.metrics()
13
+ .then((result) => {
14
+ res.setHeader(CONTENT_TYPE, options.metrics.register.contentType);
15
+ res.end(result);
16
+ })
17
+ .catch((err) => {
18
+ res.setHeader(CONTENT_TYPE, JSON_CONTENT);
19
+ const errResponse = {
20
+ statusCode: 500,
21
+ title: http.STATUS_CODES[500],
22
+ message: err.message,
23
+ };
24
+
25
+ res.end(JSON.stringify(errResponse), null, 2);
26
+ });
27
+
28
+ module.exports = {
29
+ healthCheckRoute,
30
+ metricsRoute,
31
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mimik/init",
3
- "version": "3.9.4",
3
+ "version": "5.0.0",
4
4
  "description": "Init process for micro-service",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -29,15 +29,15 @@
29
29
  "url": "https://bitbucket.org/mimiktech/init"
30
30
  },
31
31
  "dependencies": {
32
- "@mimik/address-helper": "^1.6.7",
32
+ "@mimik/address-helper": "^1.6.9",
33
+ "@mimik/api-helper": "^1.0.0",
33
34
  "@mimik/healthcheck": "^1.5.10",
34
- "@mimik/oauth-helper": "^2.2.0",
35
- "@mimik/public-helper": "^1.6.2",
35
+ "@mimik/oauth-helper": "^3.0.0",
36
+ "@mimik/public-helper": "^2.0.0",
36
37
  "@mimik/request-helper": "^1.7.8",
37
- "@mimik/response-helper": "^2.6.3",
38
+ "@mimik/response-helper": "^3.0.0",
38
39
  "@mimik/sumologic-winston-logger": "^1.6.15",
39
- "@mimik/swagger-helper": "^3.0.5",
40
- "@mimik/systeminfo": "^2.3.12",
40
+ "@mimik/systeminfo": "^3.0.0",
41
41
  "bluebird": "3.7.2",
42
42
  "cors": "2.8.5",
43
43
  "helmet": "6.1.5",
@@ -46,7 +46,7 @@
46
46
  "devDependencies": {
47
47
  "@mimik/eslint-plugin-dependencies": "^2.4.5",
48
48
  "@mimik/eslint-plugin-document-env": "^1.0.5",
49
- "eslint": "8.38.0",
49
+ "eslint": "8.39.0",
50
50
  "eslint-config-airbnb": "19.0.4",
51
51
  "eslint-plugin-import": "2.27.5",
52
52
  "eslint-plugin-jsx-a11y": "6.7.1",