diff --git a/app.js b/app.js index 1b51e930..f131da42 100755 --- a/app.js +++ b/app.js @@ -69,10 +69,10 @@ if (global.settings.log_filename) { global.log4js.configure(log4jsConfig); global.logger = global.log4js.getLogger(); - -// kick off controller -if ( ! global.settings.base_url ) { - global.settings.base_url = '/api/*'; +if (!global.settings.routes) { + console.error('Missing environment paramenter "routes". Please review your configuration file.'); + console.error("Available environments: " + availableEnvironments.join(', ')); + process.exit(1); } const version = require("./package").version; diff --git a/app/controllers/api-router.js b/app/controllers/api-router.js index d38fc645..6193cb61 100644 --- a/app/controllers/api-router.js +++ b/app/controllers/api-router.js @@ -24,7 +24,8 @@ const cors = require('../middlewares/cors'); const servedByHostHeader = require('../middlewares/served-by-host-header'); module.exports = class ApiRouter { - constructor ({ redisPool, metadataBackend, statsClient, dataIngestionLogger }) { + constructor ({ routes, redisPool, metadataBackend, statsClient, dataIngestionLogger }) { + this.routes = routes; this.statsClient = statsClient; const userLimitsServiceOptions = { @@ -68,6 +69,10 @@ module.exports = class ApiRouter { route (app) { const apiRouter = router({ mergeParams: true }); + const paths = this.routes.paths || []; + const middlewares = this.routes.middlewares || []; + + middlewares.forEach(middleware => apiRouter.use(middleware())); apiRouter.use(socketTimeout()); apiRouter.use(logger()); @@ -79,6 +84,6 @@ module.exports = class ApiRouter { this.copyController.route(apiRouter); this.jobController.route(apiRouter); - app.use(`${global.settings.base_url}`, apiRouter); + paths.forEach(path => app.use(path, apiRouter)); } }; diff --git a/app/controllers/health_check_controller.js b/app/controllers/health_check_controller.js index ef19f8a3..8c6369d7 100644 --- a/app/controllers/health_check_controller.js +++ b/app/controllers/health_check_controller.js @@ -3,12 +3,17 @@ const HealthCheckBackend = require('../monitoring/health_check'); module.exports = class HealthCheckController { - constructor () { + constructor ({ routes }) { + this.routes = routes; this.healthCheckBackend = new HealthCheckBackend(global.settings.disabled_file); } route (app) { - app.get(`${global.settings.base_url}/health`, healthCheck({ healthCheckBackend: this.healthCheckBackend })); + const paths = this.routes.paths || []; + + paths.forEach(path => app.get(`${path}/health`, healthCheck({ + healthCheckBackend: this.healthCheckBackend + }))); } }; diff --git a/app/controllers/version_controller.js b/app/controllers/version_controller.js index 03c99ba9..75c5c019 100644 --- a/app/controllers/version_controller.js +++ b/app/controllers/version_controller.js @@ -5,8 +5,14 @@ const versions = { }; module.exports = class VersionController { + constructor ({ routes }) { + this.routes = routes; + } + route (app) { - app.get(`${global.settings.base_url}/version`, version()); + const paths = this.routes.paths || []; + + paths.forEach(path => app.get(`${path}/version`, version())); } }; diff --git a/app/server.js b/app/server.js index 904d929e..3c15e047 100644 --- a/app/server.js +++ b/app/server.js @@ -61,13 +61,27 @@ module.exports = function serverFactory (statsClient) { const dataIngestionLogger = new Logger(global.settings.dataIngestionLogPath, 'data-ingestion'); app.dataIngestionLogger = dataIngestionLogger; - const healthCheckController = new HealthCheckController(); + // FIXME: health controller should be atached to the main entry point: "/" + // instead of "/api/v1/" + const healthCheckController = new HealthCheckController({ + routes: global.settings.routes + }); healthCheckController.route(app); - const versionController = new VersionController(); + // FIXME: version controller should be atached to the main entry point: "/" + // instead of "/api/v1/" + const versionController = new VersionController({ + routes: global.settings.routes + }); versionController.route(app); - const apiRouter = new ApiRouter({ redisPool, metadataBackend, statsClient, dataIngestionLogger }); + const apiRouter = new ApiRouter({ + routes: global.settings.routes, + redisPool, + metadataBackend, + statsClient, + dataIngestionLogger + }); apiRouter.route(app); const isBatchProcess = process.argv.indexOf('--no-batch') === -1; diff --git a/config/environments/development.js.example b/config/environments/development.js.example index 845f453c..c9dbae48 100644 --- a/config/environments/development.js.example +++ b/config/environments/development.js.example @@ -1,9 +1,23 @@ // Time in milliseconds to force GC cycle. // Disable by using <=0 value. module.exports.gc_interval = 10000; -// In case the base_url has a :user param the username will be the one specified in the URL, -// otherwise it will fallback to extract the username from the host header. -module.exports.base_url = '(?:/api/:version|/user/:user/api/:version)'; +module.exports.routes = { + paths: [ + // In case the base_url has a :user param the username will be the one specified in the URL, + // otherwise it will fallback to extract the username from the host header. + '/api/:version', + '/user/:user/api/:version', + ], + // Attach middlewares at the begining of the req/res cycle + // to perform custom operations. + middlewares: [ + function noop () { + return function noopMiddleware (req, res, next) { + next(); + } + } + ] +}; // If useProfiler is true every response will be served with an // X-SQLAPI-Profile header containing elapsed timing for various // steps taken for producing the response. diff --git a/config/environments/production.js.example b/config/environments/production.js.example index ac663399..85b6cf2a 100644 --- a/config/environments/production.js.example +++ b/config/environments/production.js.example @@ -1,9 +1,23 @@ // Time in milliseconds to force GC cycle. // Disable by using <=0 value. module.exports.gc_interval = 10000; -// In case the base_url has a :user param the username will be the one specified in the URL, -// otherwise it will fallback to extract the username from the host header. -module.exports.base_url = '(?:/api/:version|/user/:user/api/:version)'; +module.exports.routes = { + paths: [ + // In case the base_url has a :user param the username will be the one specified in the URL, + // otherwise it will fallback to extract the username from the host header. + '/api/:version', + '/user/:user/api/:version', + ], + // Attach middlewares at the begining of the req/res cycle + // to perform custom operations. + middlewares: [ + function noop () { + return function noopMiddleware (req, res, next) { + next(); + } + } + ] +}; // If useProfiler is true every response will be served with an // X-SQLAPI-Profile header containing elapsed timing for various // steps taken for producing the response. diff --git a/config/environments/staging.js.example b/config/environments/staging.js.example index 06e91ec5..65ca48fe 100644 --- a/config/environments/staging.js.example +++ b/config/environments/staging.js.example @@ -1,9 +1,23 @@ // Time in milliseconds to force GC cycle. // Disable by using <=0 value. module.exports.gc_interval = 10000; -// In case the base_url has a :user param the username will be the one specified in the URL, -// otherwise it will fallback to extract the username from the host header. -module.exports.base_url = '(?:/api/:version|/user/:user/api/:version)'; +module.exports.routes = { + paths: [ + // In case the base_url has a :user param the username will be the one specified in the URL, + // otherwise it will fallback to extract the username from the host header. + '/api/:version', + '/user/:user/api/:version', + ], + // Attach middlewares at the begining of the req/res cycle + // to perform custom operations. + middlewares: [ + function noop () { + return function noopMiddleware (req, res, next) { + next(); + } + } + ] +}; // If useProfiler is true every response will be served with an // X-SQLAPI-Profile header containing elapsed timing for various // steps taken for producing the response. diff --git a/config/environments/test.js.example b/config/environments/test.js.example index 5a123e90..6b55652a 100644 --- a/config/environments/test.js.example +++ b/config/environments/test.js.example @@ -1,9 +1,23 @@ // Time in milliseconds to force GC cycle. // Disable by using <=0 value. module.exports.gc_interval = 10000; -// In case the base_url has a :user param the username will be the one specified in the URL, -// otherwise it will fallback to extract the username from the host header. -module.exports.base_url = '(?:/api/:version|/user/:user/api/:version)'; +module.exports.routes = { + paths: [ + // In case the base_url has a :user param the username will be the one specified in the URL, + // otherwise it will fallback to extract the username from the host header. + '/api/:version', + '/user/:user/api/:version', + ], + // Attach middlewares at the begining of the req/res cycle + // to perform custom operations. + middlewares: [ + function noop () { + return function noopMiddleware (req, res, next) { + next(); + } + } + ] +}; // If useProfiler is true every response will be served with an // X-SQLAPI-Profile header containing elapsed timing for various // steps taken for producing the response.