NamedMaps controller using NamedMapMapConfigProvider
PreviewBackend with format param
This commit is contained in:
@@ -233,6 +233,8 @@ MapController.prototype.center = function(req, res) {
|
||||
|
||||
MapController.prototype.staticMap = function(req, res, width, height, zoom /* bounds */, center) {
|
||||
var format = req.params.format === 'jpg' ? 'jpeg' : 'png';
|
||||
req.params.layer = 'all';
|
||||
req.params.format = 'png';
|
||||
|
||||
var self = this;
|
||||
|
||||
@@ -245,10 +247,10 @@ MapController.prototype.staticMap = function(req, res, width, height, zoom /* bo
|
||||
assert.ifError(err);
|
||||
if (center) {
|
||||
self.previewBackend.getImage(new MapStoreMapConfigProvider(self.mapStore, req.params),
|
||||
req.params, width, height, zoom, center, this);
|
||||
format, width, height, zoom, center, this);
|
||||
} else {
|
||||
self.previewBackend.getImage(new MapStoreMapConfigProvider(self.mapStore, req.params),
|
||||
req.params, width, height, zoom /* bounds */, this);
|
||||
format, width, height, zoom /* bounds */, this);
|
||||
}
|
||||
},
|
||||
function handleImage(err, image, headers, stats) {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
var step = require('step');
|
||||
var assert = require('assert');
|
||||
var _ = require('underscore');
|
||||
var templateName = require('../backends/template_maps').templateName;
|
||||
var NamedMapsCacheEntry = require('../cache/model/named_maps_entry');
|
||||
var cors = require('../middleware/cors');
|
||||
|
||||
var MapStoreMapConfigProvider = require('windshaft').model.provider.MapStoreMapConfig;
|
||||
var NamedMapMapConfigProvider = require('../models/mapconfig/named_map_provider');
|
||||
|
||||
function NamedMapsController(app, pgConnection, mapStore, templateMaps, metadataBackend, mapBackend, tileBackend,
|
||||
@@ -28,7 +26,7 @@ function NamedMapsController(app, pgConnection, mapStore, templateMaps, metadata
|
||||
module.exports = NamedMapsController;
|
||||
|
||||
NamedMapsController.prototype.register = function(app) {
|
||||
app.get(this.templateBaseUrl + '/:template_id/:layer/:z/:x/:y.:format', cors(), this.tile.bind(this));
|
||||
app.get(this.templateBaseUrl + '/:template_id/:layer/:z/:x/:y.(:format)', cors(), this.tile.bind(this));
|
||||
app.get(this.templateBaseUrl + '/:template_id/jsonp', cors(), this.jsonp.bind(this));
|
||||
app.get(
|
||||
app.base_url_mapconfig + '/static/named/:template_id/:width/:height.:format', cors(), this.staticMap.bind(this)
|
||||
@@ -87,109 +85,23 @@ NamedMapsController.prototype.tile = function(req, res) {
|
||||
var self = this;
|
||||
|
||||
var cdbUser = req.context.user;
|
||||
var template;
|
||||
var layergroupConfig;
|
||||
var layergroupId;
|
||||
var params;
|
||||
var cacheChannel;
|
||||
|
||||
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 namedMapProvider;
|
||||
step(
|
||||
function reqParams() {
|
||||
self.app.req2params(req, this);
|
||||
},
|
||||
function getTemplate(err) {
|
||||
assert.ifError(err);
|
||||
self.templateMaps.getTemplate(cdbUser, templateName(req.params.template_id), this);
|
||||
},
|
||||
function checkExists(err, tpl) {
|
||||
assert.ifError(err);
|
||||
if (!tpl) {
|
||||
var notFoundErr = new Error(
|
||||
"Template '" + templateName(req.params.template_id) + "' of user '" + cdbUser + "' not found"
|
||||
);
|
||||
notFoundErr.http_status = 404;
|
||||
throw notFoundErr;
|
||||
}
|
||||
return tpl;
|
||||
},
|
||||
function checkAuthorized(err, tpl) {
|
||||
assert.ifError(err);
|
||||
|
||||
var authorized = false;
|
||||
try {
|
||||
authorized = self.templateMaps.isAuthorized(tpl, req.query.auth_token);
|
||||
} catch (err) {
|
||||
// we catch to add http_status
|
||||
var authorizationFailedErr = new Error('Failed to authorize template');
|
||||
authorizationFailedErr.http_status = 403;
|
||||
throw authorizationFailedErr;
|
||||
}
|
||||
if ( ! authorized ) {
|
||||
var unauthorizedErr = new Error('Unauthorized template instantiation');
|
||||
unauthorizedErr.http_status = 403;
|
||||
throw unauthorizedErr;
|
||||
}
|
||||
|
||||
return tpl;
|
||||
},
|
||||
function prepareParams(err, tpl) {
|
||||
assert.ifError(err);
|
||||
|
||||
template = tpl;
|
||||
|
||||
var templateParams = {};
|
||||
if (req.query.config) {
|
||||
try {
|
||||
templateParams = JSON.parse(req.query.config);
|
||||
} catch (e) {
|
||||
throw new Error('malformed config parameter, should be a valid JSON');
|
||||
}
|
||||
}
|
||||
|
||||
return templateParams;
|
||||
},
|
||||
function instantiateTemplate(err, templateParams) {
|
||||
assert.ifError(err);
|
||||
return self.templateMaps.instance(template, templateParams);
|
||||
},
|
||||
function prepareLayergroup(err, layergroup) {
|
||||
assert.ifError(err);
|
||||
layergroupConfig = layergroup;
|
||||
params = _.extend({}, req.params, {
|
||||
user: req.params.user
|
||||
});
|
||||
self.app.setDBParams(cdbUser, params, this);
|
||||
},
|
||||
function setApiKey(err){
|
||||
assert.ifError(err);
|
||||
self.mapBackend.createLayergroup(layergroupConfig, params, layergroupDecorator, this);
|
||||
},
|
||||
function prepareResponse(err, layergroup) {
|
||||
assert.ifError(err);
|
||||
|
||||
// added by createLayergroup
|
||||
cacheChannel = res.header('X-Cache-Channel');
|
||||
res.removeHeader('X-Cache-Channel');
|
||||
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbUser, template.name));
|
||||
|
||||
layergroupId = layergroup.layergroupid.split(":")[0];
|
||||
|
||||
return null;
|
||||
},
|
||||
function getImage(err) {
|
||||
assert.ifError(err);
|
||||
|
||||
req.params.token = layergroupId;
|
||||
self.tileBackend.getTile(new MapStoreMapConfigProvider(self.mapStore, req.params), params, this);
|
||||
function getTile() {
|
||||
namedMapProvider = new NamedMapMapConfigProvider(
|
||||
self.templateMaps,
|
||||
self.pgConnection,
|
||||
cdbUser,
|
||||
req.params.template_id,
|
||||
req.query.config,
|
||||
req.query.auth_token,
|
||||
req.params
|
||||
);
|
||||
self.tileBackend.getTile(namedMapProvider, req.params, this);
|
||||
},
|
||||
function handleImage(err, tile, headers, stats) {
|
||||
if (req.profiler) {
|
||||
@@ -201,6 +113,7 @@ NamedMapsController.prototype.tile = function(req, res) {
|
||||
}
|
||||
self.app.sendError(res, err, self.app.findStatusCode(err), 'NAMED_MAP_TILE', err);
|
||||
} else {
|
||||
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbUser, namedMapProvider.getTemplateName()));
|
||||
res.setHeader('Content-Type', headers['Content-Type']);
|
||||
res.setHeader('Cache-Control', 'public,max-age=7200,must-revalidate');
|
||||
self.app.sendResponse(res, [tile, 200]);
|
||||
@@ -215,106 +128,28 @@ NamedMapsController.prototype.staticMap = function(req, res) {
|
||||
var cdbUser = req.context.user;
|
||||
|
||||
var format = req.params.format === 'jpg' ? 'jpeg' : 'png';
|
||||
req.params.format = 'png';
|
||||
req.params.layer = 'all';
|
||||
|
||||
var template;
|
||||
var layergroupConfig;
|
||||
var layergroupId;
|
||||
var params;
|
||||
var cacheChannel;
|
||||
|
||||
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 namedMapProvider;
|
||||
step(
|
||||
function reqParams() {
|
||||
self.app.req2params(req, this);
|
||||
},
|
||||
function getTemplate(err) {
|
||||
assert.ifError(err);
|
||||
self.templateMaps.getTemplate(cdbUser, templateName(req.params.template_id), this);
|
||||
namedMapProvider = new NamedMapMapConfigProvider(
|
||||
self.templateMaps,
|
||||
self.pgConnection,
|
||||
cdbUser,
|
||||
req.params.template_id,
|
||||
req.query.config,
|
||||
req.query.auth_token,
|
||||
req.params
|
||||
);
|
||||
namedMapProvider.getTemplate(this);
|
||||
},
|
||||
function checkExists(err, tpl) {
|
||||
assert.ifError(err);
|
||||
if (!tpl) {
|
||||
var notFoundErr = new Error(
|
||||
"Template '" + templateName(req.params.template_id) + "' of user '" + cdbUser + "' not found"
|
||||
);
|
||||
notFoundErr.http_status = 404;
|
||||
throw notFoundErr;
|
||||
}
|
||||
return tpl;
|
||||
},
|
||||
function checkAuthorized(err, tpl) {
|
||||
assert.ifError(err);
|
||||
|
||||
var authorized = false;
|
||||
try {
|
||||
authorized = self.templateMaps.isAuthorized(tpl, req.query.auth_token);
|
||||
} catch (err) {
|
||||
// we catch to add http_status
|
||||
var authorizationFailedErr = new Error('Failed to authorize template');
|
||||
authorizationFailedErr.http_status = 403;
|
||||
throw authorizationFailedErr;
|
||||
}
|
||||
if ( ! authorized ) {
|
||||
var unauthorizedErr = new Error('Unauthorized template instantiation');
|
||||
unauthorizedErr.http_status = 403;
|
||||
throw unauthorizedErr;
|
||||
}
|
||||
|
||||
return tpl;
|
||||
},
|
||||
function prepareParams(err, tpl) {
|
||||
assert.ifError(err);
|
||||
|
||||
template = tpl;
|
||||
|
||||
var templateParams = {};
|
||||
if (req.query.config) {
|
||||
try {
|
||||
templateParams = JSON.parse(req.query.config);
|
||||
} catch (e) {
|
||||
throw new Error('malformed config parameter, should be a valid JSON');
|
||||
}
|
||||
}
|
||||
|
||||
return templateParams;
|
||||
},
|
||||
function instantiateTemplate(err, templateParams) {
|
||||
assert.ifError(err);
|
||||
return self.templateMaps.instance(template, templateParams);
|
||||
},
|
||||
function prepareLayergroup(err, layergroup) {
|
||||
assert.ifError(err);
|
||||
layergroupConfig = layergroup;
|
||||
params = {
|
||||
user: req.params.user
|
||||
};
|
||||
self.app.setDBParams(cdbUser, params, this);
|
||||
},
|
||||
function setApiKey(err){
|
||||
assert.ifError(err);
|
||||
self.mapBackend.createLayergroup(layergroupConfig, params, layergroupDecorator, this);
|
||||
},
|
||||
function prepareResponse(err, layergroup) {
|
||||
assert.ifError(err);
|
||||
|
||||
// added by createLayergroup
|
||||
cacheChannel = res.header('X-Cache-Channel');
|
||||
res.removeHeader('X-Cache-Channel');
|
||||
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbUser, template.name));
|
||||
|
||||
layergroupId = layergroup.layergroupid.split(":")[0];
|
||||
|
||||
return null;
|
||||
},
|
||||
function staticImageOptions(err) {
|
||||
function prepareStaticImageOptions(err, template) {
|
||||
assert.ifError(err);
|
||||
getStaticImageOptions(template, this);
|
||||
},
|
||||
@@ -332,6 +167,8 @@ NamedMapsController.prototype.staticMap = function(req, res) {
|
||||
}
|
||||
};
|
||||
|
||||
var cacheChannel = '';
|
||||
|
||||
var dbTables = cacheChannel.split(':');
|
||||
if (dbTables.length <= 1 || dbTables[1].length === 0) {
|
||||
return defaultZoomCenter;
|
||||
@@ -350,21 +187,15 @@ NamedMapsController.prototype.staticMap = function(req, res) {
|
||||
function getImage(err, imageOpts) {
|
||||
assert.ifError(err);
|
||||
|
||||
var imageParams = _.extend({}, params, {
|
||||
token: layergroupId,
|
||||
format: req.params.format
|
||||
});
|
||||
|
||||
var width = +req.params.width;
|
||||
var height = +req.params.height;
|
||||
|
||||
var provider = new MapStoreMapConfigProvider(self.mapStore, imageParams);
|
||||
if (!_.isUndefined(imageOpts.zoom) && imageOpts.center) {
|
||||
self.previewBackend.getImage(
|
||||
provider, imageParams, width, height, imageOpts.zoom, imageOpts.center, this);
|
||||
namedMapProvider, format, width, height, imageOpts.zoom, imageOpts.center, this);
|
||||
} else {
|
||||
self.previewBackend.getImage(
|
||||
provider, imageParams, width, height, imageOpts.bounds, this);
|
||||
namedMapProvider, format, width, height, imageOpts.bounds, this);
|
||||
}
|
||||
},
|
||||
function handleImage(err, image, headers, stats) {
|
||||
@@ -379,6 +210,7 @@ NamedMapsController.prototype.staticMap = function(req, res) {
|
||||
}
|
||||
self.app.sendError(res, err, self.app.findStatusCode(err), 'STATIC_VIZ_MAP', err);
|
||||
} else {
|
||||
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbUser, namedMapProvider.getTemplateName()));
|
||||
res.setHeader('Content-Type', headers['Content-Type'] || 'image/' + format);
|
||||
res.setHeader('Cache-Control', 'public,max-age=7200,must-revalidate');
|
||||
self.app.sendResponse(res, [image, 200]);
|
||||
@@ -418,7 +250,7 @@ NamedMapsController.prototype.instantiateTemplate = function(req, res, template_
|
||||
},
|
||||
function createLayergroup(err, mapConfig, rendererParams/*, context*/) {
|
||||
assert.ifError(err);
|
||||
self.mapBackend.createLayergroup(mapConfig, rendererParams, layergroupDecorator, this);
|
||||
self.mapBackend.createLayergroup(mapConfig.obj(), rendererParams, layergroupDecorator, this);
|
||||
},
|
||||
function prepareResponse(err, layergroup) {
|
||||
if (err) {
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
var _ = require('underscore');
|
||||
var assert = require('assert');
|
||||
var dot = require('dot');
|
||||
var step = require('step');
|
||||
var MapConfig = require('windshaft').model.MapConfig;
|
||||
var templateName = require('../../backends/template_maps').templateName;
|
||||
|
||||
function NamedMapMapConfigProvider(templateMaps, pgConnection, owner, templateId, config, authToken, params) {
|
||||
this.templateMaps = templateMaps;
|
||||
this.pgConnection = pgConnection;
|
||||
this.owner = owner;
|
||||
this.templateId = templateId;
|
||||
this.templateName = templateName(templateId);
|
||||
this.config = config;
|
||||
this.authToken = authToken;
|
||||
this.params = params;
|
||||
@@ -25,51 +27,19 @@ function NamedMapMapConfigProvider(templateMaps, pgConnection, owner, templateId
|
||||
module.exports = NamedMapMapConfigProvider;
|
||||
|
||||
NamedMapMapConfigProvider.prototype.getMapConfig = function(callback) {
|
||||
if (this.err !== null || this.mapConfig !== null) {
|
||||
if (!!this.err || this.mapConfig !== null) {
|
||||
return callback(this.err, this.mapConfig, this.rendererParams, this.context);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
var mapConfig;
|
||||
var mapConfig = null;
|
||||
var rendererParams;
|
||||
var context = {};
|
||||
|
||||
step(
|
||||
function getTemplate(err) {
|
||||
assert.ifError(err);
|
||||
self.templateMaps.getTemplate(self.owner, templateName(self.templateId), this);
|
||||
},
|
||||
function checkExists(err, tpl) {
|
||||
assert.ifError(err);
|
||||
if (!tpl) {
|
||||
var notFoundErr = new Error(
|
||||
"Template '" + templateName(self.templateId) + "' of user '" + self.owner + "' not found"
|
||||
);
|
||||
notFoundErr.http_status = 404;
|
||||
throw notFoundErr;
|
||||
}
|
||||
return tpl;
|
||||
},
|
||||
function checkAuthorized(err, tpl) {
|
||||
assert.ifError(err);
|
||||
|
||||
var authorized = false;
|
||||
try {
|
||||
authorized = self.templateMaps.isAuthorized(tpl, self.authToken);
|
||||
} catch (err) {
|
||||
// we catch to add http_status
|
||||
var authorizationFailedErr = new Error('Failed to authorize template');
|
||||
authorizationFailedErr.http_status = 403;
|
||||
throw authorizationFailedErr;
|
||||
}
|
||||
if ( ! authorized ) {
|
||||
var unauthorizedErr = new Error('Unauthorized template instantiation');
|
||||
unauthorizedErr.http_status = 403;
|
||||
throw unauthorizedErr;
|
||||
}
|
||||
|
||||
return tpl;
|
||||
function getTemplate() {
|
||||
self.getTemplate(this);
|
||||
},
|
||||
function prepareParams(err, tpl) {
|
||||
assert.ifError(err);
|
||||
@@ -101,7 +71,7 @@ NamedMapMapConfigProvider.prototype.getMapConfig = function(callback) {
|
||||
},
|
||||
function cacheAndReturnMapConfig(err) {
|
||||
self.err = err;
|
||||
self.mapConfig = mapConfig;
|
||||
self.mapConfig = (mapConfig === null) ? null : MapConfig.create(mapConfig);
|
||||
self.rendererParams = rendererParams;
|
||||
self.context = context;
|
||||
return callback(self.err, self.mapConfig, self.rendererParams, self.context);
|
||||
@@ -109,8 +79,58 @@ NamedMapMapConfigProvider.prototype.getMapConfig = function(callback) {
|
||||
);
|
||||
};
|
||||
|
||||
NamedMapMapConfigProvider.prototype.getTemplate = function(callback) {
|
||||
var self = this;
|
||||
|
||||
if (!!this.err || this.template !== null) {
|
||||
return callback(this.err, this.template);
|
||||
}
|
||||
|
||||
step(
|
||||
function getTemplate() {
|
||||
self.templateMaps.getTemplate(self.owner, self.templateName, this);
|
||||
},
|
||||
function checkExists(err, tpl) {
|
||||
assert.ifError(err);
|
||||
if (!tpl) {
|
||||
var notFoundErr = new Error(
|
||||
"Template '" + self.templateName + "' of user '" + self.owner + "' not found"
|
||||
);
|
||||
notFoundErr.http_status = 404;
|
||||
throw notFoundErr;
|
||||
}
|
||||
return tpl;
|
||||
},
|
||||
function checkAuthorized(err, tpl) {
|
||||
assert.ifError(err);
|
||||
|
||||
var authorized = false;
|
||||
try {
|
||||
authorized = self.templateMaps.isAuthorized(tpl, self.authToken);
|
||||
} catch (err) {
|
||||
// we catch to add http_status
|
||||
var authorizationFailedErr = new Error('Failed to authorize template');
|
||||
authorizationFailedErr.http_status = 403;
|
||||
throw authorizationFailedErr;
|
||||
}
|
||||
if ( ! authorized ) {
|
||||
var unauthorizedErr = new Error('Unauthorized template instantiation');
|
||||
unauthorizedErr.http_status = 403;
|
||||
throw unauthorizedErr;
|
||||
}
|
||||
|
||||
return tpl;
|
||||
},
|
||||
function cacheAndReturnTemplate(err, template) {
|
||||
self.err = err;
|
||||
self.template = template;
|
||||
return callback(self.err, self.template);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
NamedMapMapConfigProvider.prototype.getKey = function() {
|
||||
return createKey(this.params);
|
||||
return this.createKey();
|
||||
};
|
||||
|
||||
NamedMapMapConfigProvider.prototype.getCacheBuster = function() {
|
||||
@@ -118,24 +138,29 @@ NamedMapMapConfigProvider.prototype.getCacheBuster = function() {
|
||||
};
|
||||
|
||||
NamedMapMapConfigProvider.prototype.filter = function(key) {
|
||||
var regex = new RegExp('^' + createKey(this.params, true) + '.*');
|
||||
var regex = new RegExp('^' + this.createKey(true) + '.*');
|
||||
return key && key.match(regex);
|
||||
};
|
||||
|
||||
// Configure bases for cache keys suitable for string interpolation
|
||||
var baseKey = '<%= dbname %>:<%= owner %>:<%= templateName %>';
|
||||
var renderKey = baseKey + ':<%= authToken %>:<%= configHash %>:<%= layer %>:<%= scale_factor %>';
|
||||
// Create a string ID/key from a set of params
|
||||
function createKey(params, base) {
|
||||
return _.template(base ? baseKey : renderKey, _.defaults({}, params, {
|
||||
var baseKey = '{{=it.dbname}}:{{=it.owner}}:{{=it.templateName}}';
|
||||
var rendererKey = baseKey + ':{{=it.authToken}}:{{=it.configHash}}:{{=it.format}}:{{=it.layer}}:{{=it.scale_factor}}';
|
||||
|
||||
var baseKeyTpl = dot.template(baseKey);
|
||||
var rendererKeyTpl = dot.template(rendererKey);
|
||||
|
||||
NamedMapMapConfigProvider.prototype.createKey = function(base) {
|
||||
var tplValues = _.defaults({}, this.params, {
|
||||
dbname: '',
|
||||
owner: '',
|
||||
templateName: '',
|
||||
authToken: '',
|
||||
configHash: '',
|
||||
owner: this.owner,
|
||||
templateName: this.templateName,
|
||||
authToken: this.authToken || '',
|
||||
configHash: this.config && this.config.toString() || '',
|
||||
layer: '',
|
||||
scale_factor: 1
|
||||
}));
|
||||
}
|
||||
});
|
||||
return (base) ? baseKeyTpl(tplValues) : rendererKeyTpl(tplValues);
|
||||
};
|
||||
|
||||
NamedMapMapConfigProvider.prototype.setDBParams = function(cdbuser, params, callback) {
|
||||
var self = this;
|
||||
@@ -151,4 +176,8 @@ NamedMapMapConfigProvider.prototype.setDBParams = function(cdbuser, params, call
|
||||
callback(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
NamedMapMapConfigProvider.prototype.getTemplateName = function() {
|
||||
return this.templateName;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user