From 585b5929aa760de772bdb6cb3a071a252f21985c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa=20Aubert?= Date: Tue, 6 Mar 2018 16:19:53 +0100 Subject: [PATCH] Middlewarify tile and layer endpoints --- lib/cartodb/controllers/layergroup.js | 157 +++++++++++++++----------- 1 file changed, 91 insertions(+), 66 deletions(-) diff --git a/lib/cartodb/controllers/layergroup.js b/lib/cartodb/controllers/layergroup.js index 7afd2346..e07ba56b 100644 --- a/lib/cartodb/controllers/layergroup.js +++ b/lib/cartodb/controllers/layergroup.js @@ -51,7 +51,8 @@ LayergroupController.prototype.register = function(app) { cors(), userMiddleware, this.prepareContext, - this.tile.bind(this), + this.getMapStoreMapConfigProvider(this.mapStore, this.userLimitsApi), + this.tile(this.tileBackend), vectorError() ); @@ -60,7 +61,8 @@ LayergroupController.prototype.register = function(app) { cors(), userMiddleware, this.prepareContext, - this.tile.bind(this), + this.getMapStoreMapConfigProvider(this.mapStore, this.userLimitsApi), + this.tile(this.tileBackend), vectorError() ); @@ -70,7 +72,8 @@ LayergroupController.prototype.register = function(app) { userMiddleware, validateLayerRouteMiddleware, this.prepareContext, - this.layer.bind(this), + this.getMapStoreMapConfigProvider(this.mapStore, this.userLimitsApi), + this.layer(this.tileBackend), vectorError() ); @@ -269,80 +272,102 @@ LayergroupController.prototype.attributes = function (attributesBackend) { }.bind(this); }; -// Gets a tile for a given token and set of tile ZXY coords. (OSM style) -LayergroupController.prototype.tile = function(req, res, next) { - req.profiler.start('windshaft.map_tile'); - this.tileOrLayer(req, res, next); -}; - -// Gets a tile for a given token, layer set of tile ZXY coords. (OSM style) -LayergroupController.prototype.layer = function(req, res, next) { - req.profiler.start('windshaft.maplayer_tile'); - this.tileOrLayer(req, res, next); -}; - -LayergroupController.prototype.tileOrLayer = function (req, res, next) { - var self = this; - - step( - function mapController$getTileOrGrid() { - self.tileBackend.getTile( - new MapStoreMapConfigProvider(self.mapStore, res.locals.user, self.userLimitsApi, res.locals), - res.locals, this - ); - }, - function mapController$finalize(err, tile, headers, stats) { - req.profiler.add(stats); - self.finalizeGetTileOrGrid(err, req, res, tile, headers, next); - } - ); -}; - function getStatusCode(tile, format){ return tile.length===0 && format==='mvt'? 204:200; } -// This function is meant for being called as the very last -// step by all endpoints serving tiles or grids -LayergroupController.prototype.finalizeGetTileOrGrid = function(err, req, res, tile, headers, next) { - var supportedFormats = { - grid_json: true, - json_torque: true, - torque_json: true, - png: true, - png32: true, - mvt: true - }; +const supportedFormats = { + grid_json: true, + json_torque: true, + torque_json: true, + png: true, + png32: true, + mvt: true +}; - var formatStat = 'invalid'; - if (req.params.format) { - var format = req.params.format.replace('.', '_'); - if (supportedFormats[format]) { - formatStat = format; - } +function parseFormat (format = null) { + const prettyFormat = format.replace('.', '_'); + let formatStat = 'invalid'; + + if (supportedFormats[prettyFormat]) { + formatStat = prettyFormat; } - if (err) { - // See https://github.com/Vizzuality/Windshaft-cartodb/issues/68 - var errMsg = err.message ? ( '' + err.message ) : ( '' + err ); + return formatStat; +} - // Rewrite mapnik parsing errors to start with layer number - var matches = errMsg.match("(.*) in style 'layer([0-9]+)'"); - if (matches) { - errMsg = 'style'+matches[2]+': ' + matches[1]; - } - err.message = errMsg; +function augmentError (err) { + // See https://github.com/Vizzuality/Windshaft-cartodb/issues/68 + let errMsg = err.message ? ( '' + err.message ) : ( '' + err ); - err.label = 'TILE RENDER'; - next(err); + // Rewrite mapnik parsing errors to start with layer number + const matches = errMsg.match("(.*) in style 'layer([0-9]+)'"); - global.statsClient.increment('windshaft.tiles.error'); - global.statsClient.increment('windshaft.tiles.' + formatStat + '.error'); - } else { - this.sendResponse(req, res, tile, getStatusCode(tile, formatStat), headers); - global.statsClient.increment('windshaft.tiles.success'); - global.statsClient.increment('windshaft.tiles.' + formatStat + '.success'); + if (matches) { + errMsg = 'style' + matches[2] + ': ' + matches[1]; } + + err.message = errMsg; + err.label = 'TILE RENDER'; + + return err; +} + +LayergroupController.prototype.tile = function (tileBackend) { + return function tileMiddleware (req, res, next) { + req.profiler.start('windshaft.map_tile'); + + const { mapConfigProvider } = res.locals; + const params = getRequestParams(res.locals); + + tileBackend.getTile(mapConfigProvider, params, (err, tile, headers, stats) => { + req.profiler.add(stats); + + const formatStat = parseFormat(req.params.format); + + if (err) { + next(augmentError(err)); + + global.statsClient.increment('windshaft.tiles.error'); + global.statsClient.increment('windshaft.tiles.' + formatStat + '.error'); + + return; + } + + this.sendResponse(req, res, tile, getStatusCode(tile, formatStat), headers); + + global.statsClient.increment('windshaft.tiles.success'); + global.statsClient.increment('windshaft.tiles.' + formatStat + '.success'); + }); + }.bind(this); +}; + +LayergroupController.prototype.layer = function (tileBackend) { + return function layerMiddleware (req, res, next) { + req.profiler.start('windshaft.maplayer_tile'); + + const { mapConfigProvider } = res.locals; + const params = getRequestParams(res.locals); + + tileBackend.getTile(mapConfigProvider, params, (err, tile, headers, stats) => { + req.profiler.add(stats); + + const formatStat = parseFormat(req.params.format); + + if (err) { + next(augmentError(err)); + + global.statsClient.increment('windshaft.tiles.error'); + global.statsClient.increment('windshaft.tiles.' + formatStat + '.error'); + + return; + } + + this.sendResponse(req, res, tile, getStatusCode(tile, formatStat), headers); + global.statsClient.increment('windshaft.tiles.success'); + global.statsClient.increment('windshaft.tiles.' + formatStat + '.success'); + }); + }.bind(this); }; LayergroupController.prototype.center = function (previewBackend) {