From cfdff61d0844b7f82e73e9e14202aa06507e72a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa=20Aubert?= Date: Wed, 4 Apr 2018 15:52:54 +0200 Subject: [PATCH] Create map & template routers to skip unneeded middlewares in monitor endpoints --- lib/cartodb/controllers/factory.js | 150 +++---------------- lib/cartodb/controllers/map-router.js | 160 +++++++++++++++++++++ lib/cartodb/controllers/template-router.js | 92 ++++++++++++ lib/cartodb/server.js | 45 +----- 4 files changed, 271 insertions(+), 176 deletions(-) create mode 100644 lib/cartodb/controllers/map-router.js create mode 100644 lib/cartodb/controllers/template-router.js diff --git a/lib/cartodb/controllers/factory.js b/lib/cartodb/controllers/factory.js index 4826d726..4e4365e1 100644 --- a/lib/cartodb/controllers/factory.js +++ b/lib/cartodb/controllers/factory.js @@ -1,5 +1,3 @@ -const { Router: router } = require('express'); - const RedisPool = require('redis-mpool'); const cartodbRedis = require('cartodb-redis'); @@ -40,23 +38,13 @@ const ResourceLocator = require('../models/resource-locator'); const LayergroupMetadata = require('../utils/layergroup-metadata'); const RendererStatsReporter = require('../stats/reporter/renderer'); -const AnalysisLayergroupController = require('./layergroup/analysis'); -const AttributesLayergroupController = require('./layergroup/attributes'); -const DataviewLayergroupController = require('./layergroup/dataview'); -const PreviewLayergroupController = require('./layergroup/preview'); -const TileLayergroupController = require('./layergroup/tile'); - -const AnonymousMapController = require('./map/anonymous'); -const NamedMapController = require('./map/named'); - -const AdminTemplateController = require('./template/admin'); -const PreviewTemplateController = require('./template/preview'); -const TileTemplateController = require('./template/tile'); - -const AnalysesController = require('./analyses'); +const MapRouter = require('./map-router'); +const TemplateRouter = require('./template-router'); module.exports = class ControllersFactory { constructor ({ serverOptions, environmentOptions }) { + this.serverOptions = serverOptions; + const redisOptions = Object.assign({}, environmentOptions.redis, { name: 'windshaft-server', unwatchOnRelease: false, @@ -65,7 +53,7 @@ module.exports = class ControllersFactory { const redisPool = new RedisPool(redisOptions); - redisPool.on('status', function(status) { + redisPool.on('status', function (status) { var keyPrefix = 'windshaft.redis-pool.' + status.name + '.db' + status.db + '.'; global.statsClient.gauge(keyPrefix + 'count', status.count); global.statsClient.gauge(keyPrefix + 'unused', status.unused); @@ -153,146 +141,40 @@ module.exports = class ControllersFactory { templateMaps.on(eventType, namedMapProviderCache.invalidate.bind(namedMapProviderCache)); }); - this.mapConfigBasePath = serverOptions.base_url_mapconfig; - this.templateBasePath = serverOptions.base_url_templated; - - this.analysisLayergroupController = new AnalysisLayergroupController( + const collaborators = { analysisStatusBackend, - pgConnection, - mapStore, - userLimitsApi, - layergroupAffectedTablesCache, - authApi, - surrogateKeysCache - ); - - this.attributesLayergroupController = new AttributesLayergroupController( attributesBackend, - pgConnection, - mapStore, - userLimitsApi, - layergroupAffectedTablesCache, - authApi, - surrogateKeysCache - ); - - this.dataviewLayergroupController = new DataviewLayergroupController( dataviewBackend, - pgConnection, - mapStore, - userLimitsApi, - layergroupAffectedTablesCache, - authApi, - surrogateKeysCache - ); - - this.previewLayergroupController = new PreviewLayergroupController( previewBackend, - pgConnection, - mapStore, - userLimitsApi, - layergroupAffectedTablesCache, - authApi, - surrogateKeysCache - ); - - this.tileLayergroupController = new TileLayergroupController( tileBackend, pgConnection, mapStore, userLimitsApi, layergroupAffectedTablesCache, authApi, - surrogateKeysCache - ); - - this.anonymousMapController = new AnonymousMapController( - pgConnection, + surrogateKeysCache, templateMaps, mapBackend, metadataBackend, - surrogateKeysCache, - userLimitsApi, - layergroupAffectedTablesCache, mapConfigAdapter, statsBackend, - authApi, - layergroupMetadata - ); - - this.namedMapController = new NamedMapController( - pgConnection, - templateMaps, - mapBackend, - metadataBackend, - surrogateKeysCache, - userLimitsApi, - layergroupAffectedTablesCache, - mapConfigAdapter, - statsBackend, - authApi, - layergroupMetadata - ); - - this.tileTemplateController = new TileTemplateController( + layergroupMetadata, namedMapProviderCache, - tileBackend, - surrogateKeysCache, - pgConnection, - authApi, - userLimitsApi - ); + tablesExtentApi + }; - this.previewTemplateController = new PreviewTemplateController( - namedMapProviderCache, - previewBackend, - surrogateKeysCache, - tablesExtentApi, - metadataBackend, - pgConnection, - authApi, - userLimitsApi - ); - - this.adminTemplateController = new AdminTemplateController( - authApi, - templateMaps, - userLimitsApi - ); - - this.analysesController = new AnalysesController( - pgConnection, - authApi, - userLimitsApi - ); + this.mapRouter = new MapRouter({ collaborators, serverOptions }); + this.templateRouter = new TemplateRouter({ collaborators, serverOptions }); } - regist (api) { + register (app) { // FIXME: we need a better way to reset cache while running tests if (process.env.NODE_ENV === 'test') { - api.layergroupAffectedTablesCache = this.layergroupAffectedTablesCache; + app.layergroupAffectedTablesCache = this.layergroupAffectedTablesCache; } - const mapRouter = router(); - - this.analysisLayergroupController.register(mapRouter); - this.attributesLayergroupController.register(mapRouter); - this.dataviewLayergroupController.register(mapRouter); - this.previewLayergroupController.register(mapRouter); - this.tileLayergroupController.register(mapRouter); - this.anonymousMapController.register(mapRouter); - this.previewTemplateController.register(mapRouter); - this.analysesController.register(mapRouter); - - api.use(this.mapConfigBasePath, mapRouter); - - const templateRouter = router(); - - this.namedMapController.register(templateRouter); - this.tileTemplateController.register(templateRouter); - this.adminTemplateController.register(templateRouter); - - api.use(this.templateBasePath, templateRouter); + this.mapRouter.register(app); + this.templateRouter.register(app); } }; diff --git a/lib/cartodb/controllers/map-router.js b/lib/cartodb/controllers/map-router.js new file mode 100644 index 00000000..0b72572d --- /dev/null +++ b/lib/cartodb/controllers/map-router.js @@ -0,0 +1,160 @@ +const { Router: router } = require('express'); + +const logger = require('../middleware/logger'); +const bodyParser = require('body-parser'); +const servedByHostHeader = require('../middleware/served-by-host-header'); +const stats = require('../middleware/stats'); +const lzmaMiddleware = require('../middleware/lzma'); +const cors = require('../middleware/cors'); +const user = require('../middleware/user'); +const syntaxError = require('../middleware/syntax-error'); +const errorMiddleware = require('../middleware/error-middleware'); + +const AnalysisLayergroupController = require('./layergroup/analysis'); +const AttributesLayergroupController = require('./layergroup/attributes'); +const DataviewLayergroupController = require('./layergroup/dataview'); +const PreviewLayergroupController = require('./layergroup/preview'); +const TileLayergroupController = require('./layergroup/tile'); +const AnonymousMapController = require('./map/anonymous'); +const PreviewTemplateController = require('./template/preview'); +const AnalysesController = require('./analyses'); + +module.exports = class MapRouter { + constructor ({ collaborators, serverOptions }) { + this.serverOptions = serverOptions; + + const { + analysisStatusBackend, + attributesBackend, + dataviewBackend, + previewBackend, + tileBackend, + pgConnection, + mapStore, + userLimitsApi, + layergroupAffectedTablesCache, + authApi, + surrogateKeysCache, + templateMaps, + mapBackend, + metadataBackend, + mapConfigAdapter, + statsBackend, + layergroupMetadata, + namedMapProviderCache, + tablesExtentApi + } = collaborators; + + this.analysisLayergroupController = new AnalysisLayergroupController( + analysisStatusBackend, + pgConnection, + mapStore, + userLimitsApi, + layergroupAffectedTablesCache, + authApi, + surrogateKeysCache + ); + + this.attributesLayergroupController = new AttributesLayergroupController( + attributesBackend, + pgConnection, + mapStore, + userLimitsApi, + layergroupAffectedTablesCache, + authApi, + surrogateKeysCache + ); + + this.dataviewLayergroupController = new DataviewLayergroupController( + dataviewBackend, + pgConnection, + mapStore, + userLimitsApi, + layergroupAffectedTablesCache, + authApi, + surrogateKeysCache + ); + + this.previewLayergroupController = new PreviewLayergroupController( + previewBackend, + pgConnection, + mapStore, + userLimitsApi, + layergroupAffectedTablesCache, + authApi, + surrogateKeysCache + ); + + this.tileLayergroupController = new TileLayergroupController( + tileBackend, + pgConnection, + mapStore, + userLimitsApi, + layergroupAffectedTablesCache, + authApi, + surrogateKeysCache + ); + + this.anonymousMapController = new AnonymousMapController( + pgConnection, + templateMaps, + mapBackend, + metadataBackend, + surrogateKeysCache, + userLimitsApi, + layergroupAffectedTablesCache, + mapConfigAdapter, + statsBackend, + authApi, + layergroupMetadata + ); + + this.previewTemplateController = new PreviewTemplateController( + namedMapProviderCache, + previewBackend, + surrogateKeysCache, + tablesExtentApi, + metadataBackend, + pgConnection, + authApi, + userLimitsApi + ); + + this.analysesController = new AnalysesController( + pgConnection, + authApi, + userLimitsApi + ); + } + + register (app) { + const mapConfigBasePath = this.serverOptions.base_url_mapconfig; + + const mapRouter = router(); + + mapRouter.use(logger(this.serverOptions)); + mapRouter.use(bodyParser.json()); + mapRouter.use(servedByHostHeader()); + mapRouter.use(stats({ + enabled: this.serverOptions.useProfiler, + statsClient: global.statsClient + })); + mapRouter.use(lzmaMiddleware()); + mapRouter.use(cors()); + mapRouter.use(user()); + + this.analysisLayergroupController.register(mapRouter); + this.attributesLayergroupController.register(mapRouter); + this.dataviewLayergroupController.register(mapRouter); + this.previewLayergroupController.register(mapRouter); + this.tileLayergroupController.register(mapRouter); + this.anonymousMapController.register(mapRouter); + this.previewTemplateController.register(mapRouter); + this.analysesController.register(mapRouter); + + mapRouter.use(syntaxError()); + mapRouter.use(errorMiddleware()); + + app.use(mapConfigBasePath, mapRouter); + } +}; diff --git a/lib/cartodb/controllers/template-router.js b/lib/cartodb/controllers/template-router.js new file mode 100644 index 00000000..b7334c9b --- /dev/null +++ b/lib/cartodb/controllers/template-router.js @@ -0,0 +1,92 @@ +const { Router: router } = require('express'); + +const logger = require('../middleware/logger'); +const bodyParser = require('body-parser'); +const servedByHostHeader = require('../middleware/served-by-host-header'); +const stats = require('../middleware/stats'); +const lzmaMiddleware = require('../middleware/lzma'); +const cors = require('../middleware/cors'); +const user = require('../middleware/user'); +const syntaxError = require('../middleware/syntax-error'); +const errorMiddleware = require('../middleware/error-middleware'); + +const NamedMapController = require('./map/named'); +const AdminTemplateController = require('./template/admin'); +const TileTemplateController = require('./template/tile'); + +module.exports = class TemplateRouter { + constructor ({ collaborators, serverOptions }) { + this.serverOptions = serverOptions; + + const { + pgConnection, + templateMaps, + mapBackend, + metadataBackend, + surrogateKeysCache, + userLimitsApi, + layergroupAffectedTablesCache, + mapConfigAdapter, + statsBackend, + authApi, + layergroupMetadata, + namedMapProviderCache, + tileBackend, + } = collaborators; + + this.namedMapController = new NamedMapController( + pgConnection, + templateMaps, + mapBackend, + metadataBackend, + surrogateKeysCache, + userLimitsApi, + layergroupAffectedTablesCache, + mapConfigAdapter, + statsBackend, + authApi, + layergroupMetadata + ); + + this.tileTemplateController = new TileTemplateController( + namedMapProviderCache, + tileBackend, + surrogateKeysCache, + pgConnection, + authApi, + userLimitsApi + ); + + this.adminTemplateController = new AdminTemplateController( + authApi, + templateMaps, + userLimitsApi + ); + } + + register (app) { + const templateBasePath = this.serverOptions.base_url_templated; + + const templateRouter = router(); + + templateRouter.use(logger(this.serverOptions)); + templateRouter.use(bodyParser.json()); + templateRouter.use(servedByHostHeader()); + templateRouter.use(stats({ + enabled: this.serverOptions.useProfiler, + statsClient: global.statsClient + })); + templateRouter.use(lzmaMiddleware()); + templateRouter.use(cors()); + templateRouter.use(user()); + + this.namedMapController.register(templateRouter); + this.tileTemplateController.register(templateRouter); + this.adminTemplateController.register(templateRouter); + + templateRouter.use(syntaxError()); + templateRouter.use(errorMiddleware()); + + app.use(templateBasePath, templateRouter); + } +}; diff --git a/lib/cartodb/server.js b/lib/cartodb/server.js index e844f4f4..847b7090 100644 --- a/lib/cartodb/server.js +++ b/lib/cartodb/server.js @@ -5,20 +5,9 @@ const { mapnik } = windshaft; const jsonReplacer = require('./utils/json-replacer'); -const logger = require('./middleware/logger'); -const bodyParser = require('body-parser'); -const servedByHostHeader = require('./middleware/served-by-host-header'); -const stats = require('./middleware/stats'); -const lzmaMiddleware = require('./middleware/lzma'); -const cors = require('./middleware/cors'); -const user = require('./middleware/user'); - const ControllersFactory = require('./controllers/factory'); const ServerInfoController = require('./controllers/server-info'); -const syntaxError = require('./middleware/syntax-error'); -const errorMiddleware = require('./middleware/error-middleware'); - const StatsClient = require('./stats/client'); module.exports = function createServer (serverOptions) { @@ -38,41 +27,13 @@ module.exports = function createServer (serverOptions) { app.disable('etag'); app.set('json replacer', jsonReplacer()); - const api = express.Router(); - - api.use(logger(serverOptions)); - api.use(bodyParser.json()); - api.use(servedByHostHeader()); - api.use(stats({ - enabled: serverOptions.useProfiler, - statsClient: global.statsClient - })); - api.use(lzmaMiddleware()); - api.use(cors()); - api.use(user()); - const controllers = new ControllersFactory({ serverOptions, environmentOptions: global.environment }); - - controllers.regist(api); - - api.use(syntaxError()); - api.use(errorMiddleware()); - - app.use('/', api); - - const monitor = express.Router(); + controllers.register(app); const versions = getAndValidateVersions(serverOptions); + const serverInfoController = new ServerInfoController(versions); - - serverInfoController.register(monitor); - - app.use('/', monitor); - - // FIXME: we need a better way to reset cache while running tests - if (process.env.NODE_ENV === 'test') { - app.layergroupAffectedTablesCache = api.layergroupAffectedTablesCache; - } + serverInfoController.register(app); return app; };