Fix named maps controller using MapStoreMapConfig
This commit is contained in:
parent
ed096c3a1a
commit
ae2a72a810
@ -5,13 +5,17 @@ var templateName = require('../backends/template_maps').templateName;
|
|||||||
var NamedMapsCacheEntry = require('../cache/model/named_maps_entry');
|
var NamedMapsCacheEntry = require('../cache/model/named_maps_entry');
|
||||||
var cors = require('../middleware/cors');
|
var cors = require('../middleware/cors');
|
||||||
|
|
||||||
function NamedMapsController(app, templateMaps, metadataBackend, mapBackend, staticMapBackend, templateBaseUrl,
|
var MapStoreMapConfigProvider = require('windshaft').model.provider.MapStoreMapConfig;
|
||||||
surrogateKeysCache, layergroupRequestDecorator, tablesExtentApi) {
|
|
||||||
|
function NamedMapsController(app, mapStore, templateMaps, metadataBackend, mapBackend, tileBackend, previewBackend,
|
||||||
|
templateBaseUrl, surrogateKeysCache, layergroupRequestDecorator, tablesExtentApi) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
this.mapStore = mapStore;
|
||||||
this.templateMaps = templateMaps;
|
this.templateMaps = templateMaps;
|
||||||
this.metadataBackend = metadataBackend;
|
this.metadataBackend = metadataBackend;
|
||||||
this.mapBackend = mapBackend;
|
this.mapBackend = mapBackend;
|
||||||
this.staticMapBackend = staticMapBackend;
|
this.tileBackend = tileBackend;
|
||||||
|
this.previewBackend = previewBackend;
|
||||||
this.templateBaseUrl = templateBaseUrl;
|
this.templateBaseUrl = templateBaseUrl;
|
||||||
this.surrogateKeysCache = surrogateKeysCache;
|
this.surrogateKeysCache = surrogateKeysCache;
|
||||||
this.layergroupRequestDecorator = layergroupRequestDecorator;
|
this.layergroupRequestDecorator = layergroupRequestDecorator;
|
||||||
@ -29,6 +33,53 @@ NamedMapsController.prototype.register = function(app) {
|
|||||||
app.post(this.templateBaseUrl + '/:template_id', cors(), this.instantiate.bind(this));
|
app.post(this.templateBaseUrl + '/:template_id', cors(), this.instantiate.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NamedMapsController.prototype.instantiate = function(req, res) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (req.profiler) {
|
||||||
|
req.profiler.start('windshaft-cartodb.instance_template_post');
|
||||||
|
}
|
||||||
|
step(
|
||||||
|
function instantiateTemplate() {
|
||||||
|
ifInvalidContentType(req, 'template POST data must be of type application/json');
|
||||||
|
|
||||||
|
self.instantiateTemplate(req, res, req.body, this);
|
||||||
|
}, function finishInstantiation(err, response) {
|
||||||
|
self.finish_instantiation(err, response, res);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jsonp endpoint, allows to instantiate a template with a json call.
|
||||||
|
* callback query argument is mandatory
|
||||||
|
*/
|
||||||
|
NamedMapsController.prototype.jsonp = function(req, res) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (req.profiler) {
|
||||||
|
req.profiler.start('windshaft-cartodb.instance_template_get');
|
||||||
|
}
|
||||||
|
step(
|
||||||
|
function jsonp$instantiateTemplate() {
|
||||||
|
if ( req.query.callback === undefined || req.query.callback.length === 0) {
|
||||||
|
throw new Error('callback parameter should be present and be a function name');
|
||||||
|
}
|
||||||
|
var config = {};
|
||||||
|
if(req.query.config) {
|
||||||
|
try {
|
||||||
|
config = JSON.parse(req.query.config);
|
||||||
|
} catch(e) {
|
||||||
|
throw new Error('Invalid config parameter, should be a valid JSON');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.instantiateTemplate(req, res, config, this);
|
||||||
|
}, function finishInstantiation(err, response) {
|
||||||
|
self.finish_instantiation(err, response, res);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
NamedMapsController.prototype.tile = function(req, res) {
|
NamedMapsController.prototype.tile = function(req, res) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@ -135,7 +186,7 @@ NamedMapsController.prototype.tile = function(req, res) {
|
|||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
|
|
||||||
req.params.token = layergroupId;
|
req.params.token = layergroupId;
|
||||||
self.mapBackend.getTileOrGrid(req.params, this);
|
self.tileBackend.getTile(new MapStoreMapConfigProvider(self.mapStore, req.params), params, this);
|
||||||
},
|
},
|
||||||
function handleImage(err, tile, headers, stats) {
|
function handleImage(err, tile, headers, stats) {
|
||||||
if (req.profiler) {
|
if (req.profiler) {
|
||||||
@ -155,162 +206,6 @@ NamedMapsController.prototype.tile = function(req, res) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
NamedMapsController.prototype.instantiate = function(req, res) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if (req.profiler) {
|
|
||||||
req.profiler.start('windshaft-cartodb.instance_template_post');
|
|
||||||
}
|
|
||||||
step(
|
|
||||||
function instantiateTemplate() {
|
|
||||||
ifInvalidContentType(req, 'template POST data must be of type application/json');
|
|
||||||
|
|
||||||
self.instantiateTemplate(req, res, req.body, this);
|
|
||||||
}, function finishInstantiation(err, response) {
|
|
||||||
self.finish_instantiation(err, response, res);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* jsonp endpoint, allows to instantiate a template with a json call.
|
|
||||||
* callback query argument is mandatory
|
|
||||||
*/
|
|
||||||
NamedMapsController.prototype.jsonp = function(req, res) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if (req.profiler) {
|
|
||||||
req.profiler.start('windshaft-cartodb.instance_template_get');
|
|
||||||
}
|
|
||||||
step(
|
|
||||||
function jsonp$instantiateTemplate() {
|
|
||||||
if ( req.query.callback === undefined || req.query.callback.length === 0) {
|
|
||||||
throw new Error('callback parameter should be present and be a function name');
|
|
||||||
}
|
|
||||||
var config = {};
|
|
||||||
if(req.query.config) {
|
|
||||||
try {
|
|
||||||
config = JSON.parse(req.query.config);
|
|
||||||
} catch(e) {
|
|
||||||
throw new Error('Invalid config parameter, should be a valid JSON');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.instantiateTemplate(req, res, config, this);
|
|
||||||
}, function finishInstantiation(err, response) {
|
|
||||||
self.finish_instantiation(err, response, res);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Instantiate a template
|
|
||||||
NamedMapsController.prototype.instantiateTemplate = function(req, res, template_params, callback) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
var layergroupDecorator = {
|
|
||||||
beforeLayergroupCreate: function(requestMapConfig, callback) {
|
|
||||||
self.layergroupRequestDecorator.beforeLayergroupCreate(req, requestMapConfig, callback);
|
|
||||||
},
|
|
||||||
afterLayergroupCreate: function(layergroup, response, callback) {
|
|
||||||
self.layergroupRequestDecorator.afterLayergroupCreate(req, layergroup, response, callback);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var template;
|
|
||||||
var layergroup;
|
|
||||||
var cdbuser = req.context.user;
|
|
||||||
var params = {
|
|
||||||
user: req.params.user
|
|
||||||
};
|
|
||||||
// Format of template_id: [<template_owner>]@<template_id>
|
|
||||||
var tpl_id = templateName(req.params.template_id);
|
|
||||||
var auth_token = req.query.auth_token;
|
|
||||||
step(
|
|
||||||
function getTemplate(){
|
|
||||||
self.templateMaps.getTemplate(cdbuser, tpl_id, this);
|
|
||||||
},
|
|
||||||
function checkAuthorized(err, templateValue) {
|
|
||||||
if ( req.profiler ) req.profiler.done('getTemplate');
|
|
||||||
if ( err ) throw err;
|
|
||||||
if ( ! templateValue ) {
|
|
||||||
err = new Error("Template '" + tpl_id + "' of user '" + cdbuser + "' not found");
|
|
||||||
err.http_status = 404;
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
template = templateValue;
|
|
||||||
|
|
||||||
var authorized = false;
|
|
||||||
try {
|
|
||||||
authorized = self.templateMaps.isAuthorized(template, auth_token);
|
|
||||||
} catch (err) {
|
|
||||||
// we catch to add http_status
|
|
||||||
err.http_status = 403;
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
if ( ! authorized ) {
|
|
||||||
err = new Error('Unauthorized template instantiation');
|
|
||||||
err.http_status = 403;
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.profiler) {
|
|
||||||
req.profiler.done('authorizedByCert');
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.templateMaps.instance(template, template_params);
|
|
||||||
},
|
|
||||||
function prepareParams(err, instance){
|
|
||||||
if ( req.profiler ) req.profiler.done('TemplateMaps_instance');
|
|
||||||
if ( err ) throw err;
|
|
||||||
layergroup = instance;
|
|
||||||
self.app.setDBParams(cdbuser, params, this);
|
|
||||||
},
|
|
||||||
function setApiKey(err){
|
|
||||||
if ( req.profiler ) req.profiler.done('setDBParams');
|
|
||||||
if ( err ) throw err;
|
|
||||||
self.metadataBackend.getUserMapKey(cdbuser, this);
|
|
||||||
},
|
|
||||||
function createLayergroup(err, val) {
|
|
||||||
if ( req.profiler ) req.profiler.done('getUserMapKey');
|
|
||||||
if ( err ) throw err;
|
|
||||||
params.api_key = val;
|
|
||||||
self.mapBackend.createLayergroup(layergroup, params, layergroupDecorator, this);
|
|
||||||
},
|
|
||||||
function prepareResponse(err, layergroup) {
|
|
||||||
if ( err ) {
|
|
||||||
return callback(err, { errors: [''+err] });
|
|
||||||
}
|
|
||||||
var tplhash = self.templateMaps.fingerPrint(template).substring(0,8);
|
|
||||||
layergroup.layergroupid = cdbuser + '@' + tplhash + '@' + layergroup.layergroupid;
|
|
||||||
res.header('X-Layergroup-Id', layergroup.layergroupid);
|
|
||||||
|
|
||||||
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbuser, template.name));
|
|
||||||
|
|
||||||
callback(null, layergroup);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
NamedMapsController.prototype.finish_instantiation = function(err, response, res) {
|
|
||||||
if (err) {
|
|
||||||
var statusCode = 400;
|
|
||||||
response = { errors: [''+err] };
|
|
||||||
if ( ! _.isUndefined(err.http_status) ) {
|
|
||||||
statusCode = err.http_status;
|
|
||||||
}
|
|
||||||
this.app.sendError(res, response, statusCode, 'POST INSTANCE TEMPLATE', err);
|
|
||||||
} else {
|
|
||||||
this.app.sendResponse(res, [response, 200]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function ifInvalidContentType(req, description) {
|
|
||||||
if ( ! req.headers['content-type'] || req.headers['content-type'].split(';')[0] != 'application/json' ) {
|
|
||||||
throw new Error(description);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NamedMapsController.prototype.staticMap = function(req, res) {
|
NamedMapsController.prototype.staticMap = function(req, res) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@ -460,10 +355,13 @@ NamedMapsController.prototype.staticMap = function(req, res) {
|
|||||||
var width = +req.params.width;
|
var width = +req.params.width;
|
||||||
var height = +req.params.height;
|
var height = +req.params.height;
|
||||||
|
|
||||||
|
var provider = new MapStoreMapConfigProvider(self.mapStore, imageParams);
|
||||||
if (!_.isUndefined(imageOpts.zoom) && imageOpts.center) {
|
if (!_.isUndefined(imageOpts.zoom) && imageOpts.center) {
|
||||||
self.staticMapBackend.getImage(imageParams, width, height, imageOpts.zoom, imageOpts.center, this);
|
self.previewBackend.getImage(
|
||||||
|
provider, imageParams, width, height, imageOpts.zoom, imageOpts.center, this);
|
||||||
} else {
|
} else {
|
||||||
self.staticMapBackend.getImage(imageParams, width, height, imageOpts.bounds, this);
|
self.previewBackend.getImage(
|
||||||
|
provider, imageParams, width, height, imageOpts.bounds, this);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
function handleImage(err, image, headers, stats) {
|
function handleImage(err, image, headers, stats) {
|
||||||
@ -486,6 +384,115 @@ NamedMapsController.prototype.staticMap = function(req, res) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Instantiate a template
|
||||||
|
NamedMapsController.prototype.instantiateTemplate = function(req, res, template_params, callback) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var layergroupDecorator = {
|
||||||
|
beforeLayergroupCreate: function(requestMapConfig, callback) {
|
||||||
|
self.layergroupRequestDecorator.beforeLayergroupCreate(req, requestMapConfig, callback);
|
||||||
|
},
|
||||||
|
afterLayergroupCreate: function(layergroup, response, callback) {
|
||||||
|
self.layergroupRequestDecorator.afterLayergroupCreate(req, layergroup, response, callback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var template;
|
||||||
|
var layergroup;
|
||||||
|
var cdbuser = req.context.user;
|
||||||
|
var params = {
|
||||||
|
user: req.params.user
|
||||||
|
};
|
||||||
|
// Format of template_id: [<template_owner>]@<template_id>
|
||||||
|
var tpl_id = templateName(req.params.template_id);
|
||||||
|
var auth_token = req.query.auth_token;
|
||||||
|
step(
|
||||||
|
function getTemplate(){
|
||||||
|
self.templateMaps.getTemplate(cdbuser, tpl_id, this);
|
||||||
|
},
|
||||||
|
function checkAuthorized(err, templateValue) {
|
||||||
|
if ( req.profiler ) req.profiler.done('getTemplate');
|
||||||
|
if ( err ) throw err;
|
||||||
|
if ( ! templateValue ) {
|
||||||
|
err = new Error("Template '" + tpl_id + "' of user '" + cdbuser + "' not found");
|
||||||
|
err.http_status = 404;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
template = templateValue;
|
||||||
|
|
||||||
|
var authorized = false;
|
||||||
|
try {
|
||||||
|
authorized = self.templateMaps.isAuthorized(template, auth_token);
|
||||||
|
} catch (err) {
|
||||||
|
// we catch to add http_status
|
||||||
|
err.http_status = 403;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
if ( ! authorized ) {
|
||||||
|
err = new Error('Unauthorized template instantiation');
|
||||||
|
err.http_status = 403;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.profiler) {
|
||||||
|
req.profiler.done('authorizedByCert');
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.templateMaps.instance(template, template_params);
|
||||||
|
},
|
||||||
|
function prepareParams(err, instance){
|
||||||
|
if ( req.profiler ) req.profiler.done('TemplateMaps_instance');
|
||||||
|
if ( err ) throw err;
|
||||||
|
layergroup = instance;
|
||||||
|
self.app.setDBParams(cdbuser, params, this);
|
||||||
|
},
|
||||||
|
function setApiKey(err){
|
||||||
|
if ( req.profiler ) req.profiler.done('setDBParams');
|
||||||
|
if ( err ) throw err;
|
||||||
|
self.metadataBackend.getUserMapKey(cdbuser, this);
|
||||||
|
},
|
||||||
|
function createLayergroup(err, val) {
|
||||||
|
if ( req.profiler ) req.profiler.done('getUserMapKey');
|
||||||
|
if ( err ) throw err;
|
||||||
|
params.api_key = val;
|
||||||
|
self.mapBackend.createLayergroup(layergroup, params, layergroupDecorator, this);
|
||||||
|
},
|
||||||
|
function prepareResponse(err, layergroup) {
|
||||||
|
if ( err ) {
|
||||||
|
return callback(err, { errors: [''+err] });
|
||||||
|
}
|
||||||
|
var tplhash = self.templateMaps.fingerPrint(template).substring(0,8);
|
||||||
|
layergroup.layergroupid = cdbuser + '@' + tplhash + '@' + layergroup.layergroupid;
|
||||||
|
res.header('X-Layergroup-Id', layergroup.layergroupid);
|
||||||
|
|
||||||
|
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbuser, template.name));
|
||||||
|
|
||||||
|
callback(null, layergroup);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
NamedMapsController.prototype.finish_instantiation = function(err, response, res) {
|
||||||
|
if (err) {
|
||||||
|
var statusCode = 400;
|
||||||
|
response = { errors: [''+err] };
|
||||||
|
if ( ! _.isUndefined(err.http_status) ) {
|
||||||
|
statusCode = err.http_status;
|
||||||
|
}
|
||||||
|
this.app.sendError(res, response, statusCode, 'POST INSTANCE TEMPLATE', err);
|
||||||
|
} else {
|
||||||
|
this.app.sendResponse(res, [response, 200]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function ifInvalidContentType(req, description) {
|
||||||
|
if ( ! req.headers['content-type'] || req.headers['content-type'].split(';')[0] != 'application/json' ) {
|
||||||
|
throw new Error(description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getStaticImageOptions(template, callback) {
|
function getStaticImageOptions(template, callback) {
|
||||||
if (template.view) {
|
if (template.view) {
|
||||||
var zoomCenter = templateZoomCenter(template.view);
|
var zoomCenter = templateZoomCenter(template.view);
|
||||||
|
@ -321,9 +321,11 @@ module.exports = function(serverOptions) {
|
|||||||
|
|
||||||
new controller.NamedMaps(
|
new controller.NamedMaps(
|
||||||
app,
|
app,
|
||||||
|
mapStore,
|
||||||
templateMaps,
|
templateMaps,
|
||||||
metadataBackend,
|
metadataBackend,
|
||||||
mapBackend,
|
mapBackend,
|
||||||
|
tileBackend,
|
||||||
previewBackend,
|
previewBackend,
|
||||||
template_baseurl,
|
template_baseurl,
|
||||||
surrogateKeysCache,
|
surrogateKeysCache,
|
||||||
|
@ -9,7 +9,7 @@ var server = new CartodbWindshaft(serverOptions);
|
|||||||
var TemplateMaps = require('../../lib/cartodb/backends/template_maps.js');
|
var TemplateMaps = require('../../lib/cartodb/backends/template_maps.js');
|
||||||
var NamedMapsCacheEntry = require('../../lib/cartodb/cache/model/named_maps_entry');
|
var NamedMapsCacheEntry = require('../../lib/cartodb/cache/model/named_maps_entry');
|
||||||
|
|
||||||
describe.skip('named static maps', function() {
|
describe('named static maps', function() {
|
||||||
// configure redis pool instance to use in tests
|
// configure redis pool instance to use in tests
|
||||||
var redisPool = new RedisPool(global.environment.redis);
|
var redisPool = new RedisPool(global.environment.redis);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user