Middlewarify tile and layer endpoints

This commit is contained in:
Daniel García Aubert
2018-03-06 16:19:53 +01:00
parent 9b40370794
commit 585b5929aa
+91 -66
View File
@@ -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) {