Adds named maps mapconfig provider
starts using it in named map instantiation
This commit is contained in:
@@ -6,11 +6,14 @@ 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, mapStore, templateMaps, metadataBackend, mapBackend, tileBackend, previewBackend,
|
||||
templateBaseUrl, surrogateKeysCache, layergroupRequestDecorator, tablesExtentApi) {
|
||||
function NamedMapsController(app, pgConnection, mapStore, templateMaps, metadataBackend, mapBackend, tileBackend,
|
||||
previewBackend, templateBaseUrl, surrogateKeysCache, layergroupRequestDecorator,
|
||||
tablesExtentApi) {
|
||||
this.app = app;
|
||||
this.mapStore = mapStore;
|
||||
this.pgConnection = pgConnection;
|
||||
this.templateMaps = templateMaps;
|
||||
this.metadataBackend = metadataBackend;
|
||||
this.mapBackend = mapBackend;
|
||||
@@ -398,76 +401,34 @@ NamedMapsController.prototype.instantiateTemplate = function(req, res, template_
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
var mapConfigProvider = new NamedMapMapConfigProvider(
|
||||
this.templateMaps,
|
||||
this.pgConnection,
|
||||
cdbuser,
|
||||
req.params.template_id,
|
||||
template_params,
|
||||
req.query.auth_token,
|
||||
req.params
|
||||
);
|
||||
|
||||
step(
|
||||
function getTemplate(){
|
||||
self.templateMaps.getTemplate(cdbuser, tpl_id, this);
|
||||
mapConfigProvider.getMapConfig(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 createLayergroup(err, mapConfig, rendererParams/*, context*/) {
|
||||
assert.ifError(err);
|
||||
self.mapBackend.createLayergroup(mapConfig, rendererParams, layergroupDecorator, this);
|
||||
},
|
||||
function prepareResponse(err, layergroup) {
|
||||
if ( err ) {
|
||||
if (err) {
|
||||
return callback(err, { errors: [''+err] });
|
||||
}
|
||||
var tplhash = self.templateMaps.fingerPrint(template).substring(0,8);
|
||||
layergroup.layergroupid = cdbuser + '@' + tplhash + '@' + layergroup.layergroupid;
|
||||
var templateHash = self.templateMaps.fingerPrint(mapConfigProvider.template).substring(0,8);
|
||||
layergroup.layergroupid = cdbuser + '@' + templateHash + '@' + layergroup.layergroupid;
|
||||
res.header('X-Layergroup-Id', layergroup.layergroupid);
|
||||
|
||||
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbuser, template.name));
|
||||
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbuser, mapConfigProvider.template.name));
|
||||
|
||||
callback(null, layergroup);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
var _ = require('underscore');
|
||||
var assert = require('assert');
|
||||
var step = require('step');
|
||||
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.config = config;
|
||||
this.authToken = authToken;
|
||||
this.params = params;
|
||||
|
||||
// use template after call to mapConfig
|
||||
this.template = null;
|
||||
|
||||
// providing
|
||||
this.err = null;
|
||||
this.mapConfig = null;
|
||||
this.rendererParams = null;
|
||||
this.context = null;
|
||||
}
|
||||
|
||||
module.exports = NamedMapMapConfigProvider;
|
||||
|
||||
NamedMapMapConfigProvider.prototype.getMapConfig = function(callback) {
|
||||
if (this.err !== null || this.mapConfig !== null) {
|
||||
return callback(this.err, this.mapConfig, this.rendererParams, this.context);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
var mapConfig;
|
||||
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 prepareParams(err, tpl) {
|
||||
assert.ifError(err);
|
||||
|
||||
self.template = tpl;
|
||||
|
||||
var templateParams = {};
|
||||
if (self.config) {
|
||||
try {
|
||||
templateParams = _.isString(self.config) ? JSON.parse(self.config) : self.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(self.template, templateParams);
|
||||
},
|
||||
function prepareLayergroup(err, layergroup) {
|
||||
assert.ifError(err);
|
||||
mapConfig = layergroup;
|
||||
rendererParams = _.extend({}, self.params, {
|
||||
user: self.owner
|
||||
});
|
||||
self.setDBParams(self.owner, rendererParams, this);
|
||||
},
|
||||
function cacheAndReturnMapConfig(err) {
|
||||
self.err = err;
|
||||
self.mapConfig = mapConfig;
|
||||
self.rendererParams = rendererParams;
|
||||
self.context = context;
|
||||
return callback(self.err, self.mapConfig, self.rendererParams, self.context);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
NamedMapMapConfigProvider.prototype.getKey = function() {
|
||||
return createKey(this.params);
|
||||
};
|
||||
|
||||
NamedMapMapConfigProvider.prototype.getCacheBuster = function() {
|
||||
return 0;
|
||||
};
|
||||
|
||||
NamedMapMapConfigProvider.prototype.filter = function(key) {
|
||||
var regex = new RegExp('^' + createKey(this.params, 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, {
|
||||
dbname: '',
|
||||
owner: '',
|
||||
templateName: '',
|
||||
authToken: '',
|
||||
configHash: '',
|
||||
scale_factor: 1
|
||||
}));
|
||||
}
|
||||
|
||||
NamedMapMapConfigProvider.prototype.setDBParams = function(cdbuser, params, callback) {
|
||||
var self = this;
|
||||
step(
|
||||
function setAuth() {
|
||||
self.pgConnection.setDBAuth(cdbuser, params, this);
|
||||
},
|
||||
function setConn(err) {
|
||||
if ( err ) throw err;
|
||||
self.pgConnection.setDBConn(cdbuser, params, this);
|
||||
},
|
||||
function finish(err) {
|
||||
callback(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -321,6 +321,7 @@ module.exports = function(serverOptions) {
|
||||
|
||||
new controller.NamedMaps(
|
||||
app,
|
||||
pgConnection,
|
||||
mapStore,
|
||||
templateMaps,
|
||||
metadataBackend,
|
||||
|
||||
Reference in New Issue
Block a user