Upgrade Windshaft to 0.10.0, changing multilayer interface

WARNING: starting from this commit the grid fetching route changed
         to NOT include layer name nor interactivity (which is now
         specified solely as part of layergroup configuration)

Target 1.2.0 release
This commit is contained in:
Sandro Santilli 2013-03-29 16:32:26 +01:00
parent 2b2c22cdd5
commit aea107f1af
4 changed files with 211 additions and 86 deletions

View File

@ -1,11 +1,17 @@
1.1.9 1.2.0
----- -----
WARNING: starting from this commit the grid fetching route changed
to NOT include layer name nor interactivity (which is now
specified solely as part of layergroup configuration)
* Handle SQL API errors by requesting no Varnish cache * Handle SQL API errors by requesting no Varnish cache
* Fix X-Cache-Channel for multilayer (by token) responses * Fix X-Cache-Channel for multilayer (by token) responses
* Add last_modified field to POST layergroup response (#72) * Add last_modified field to POST layergroup response (#72)
* Deprecate signal handler for USR1, add handler for USR2 (#71) * Deprecate signal handler for USR1, add handler for USR2 (#71)
* Fix support for ampersend characters in CartoCSS * Fix support for ampersend characters in CartoCSS
* Add support for LZMA compressed GET parameters * Add support for LZMA compressed GET parameters
* Remove interactivity parameters from grid fetching route
1.1.8 1.1.8
----- -----

158
npm-shrinkwrap.json generated
View File

@ -13,7 +13,7 @@
"version": "1.9.2", "version": "1.9.2",
"dependencies": { "dependencies": {
"formidable": { "formidable": {
"version": "1.0.12" "version": "1.0.13"
} }
} }
}, },
@ -32,10 +32,10 @@
"version": "0.8.3" "version": "0.8.3"
}, },
"npm": { "npm": {
"version": "1.2.12", "version": "1.2.15",
"dependencies": { "dependencies": {
"semver": { "semver": {
"version": "1.1.3" "version": "1.1.4"
}, },
"ini": { "ini": {
"version": "1.1.0" "version": "1.1.0"
@ -50,7 +50,7 @@
"version": "1.2.0" "version": "1.2.0"
}, },
"minimatch": { "minimatch": {
"version": "0.2.9", "version": "0.2.11",
"dependencies": { "dependencies": {
"sigmund": { "sigmund": {
"version": "1.0.0" "version": "1.0.0"
@ -71,7 +71,7 @@
"version": "1.0.5" "version": "1.0.5"
}, },
"tar": { "tar": {
"version": "0.1.16" "version": "0.1.17"
}, },
"fstream": { "fstream": {
"version": "0.1.22" "version": "0.1.22"
@ -84,7 +84,7 @@
"from": "git://github.com/isaacs/inherits" "from": "git://github.com/isaacs/inherits"
}, },
"mkdirp": { "mkdirp": {
"version": "0.3.4" "version": "0.3.5"
}, },
"read": { "read": {
"version": "1.0.4", "version": "1.0.4",
@ -95,13 +95,13 @@
} }
}, },
"lru-cache": { "lru-cache": {
"version": "2.0.4" "version": "2.3.0"
}, },
"node-gyp": { "node-gyp": {
"version": "0.8.4" "version": "0.9.3"
}, },
"fstream-npm": { "fstream-npm": {
"version": "0.1.3", "version": "0.1.4",
"dependencies": { "dependencies": {
"fstream-ignore": { "fstream-ignore": {
"version": "0.0.6" "version": "0.0.6"
@ -124,7 +124,7 @@
"version": "0.1.2" "version": "0.1.2"
}, },
"npm-registry-client": { "npm-registry-client": {
"version": "0.2.17", "version": "0.2.18",
"dependencies": { "dependencies": {
"couch-login": { "couch-login": {
"version": "0.1.15" "version": "0.1.15"
@ -132,13 +132,13 @@
} }
}, },
"read-package-json": { "read-package-json": {
"version": "0.2.0" "version": "0.3.0"
}, },
"read-installed": { "read-installed": {
"version": "0.1.1" "version": "0.1.1"
}, },
"glob": { "glob": {
"version": "3.1.20" "version": "3.1.21"
}, },
"init-package-json": { "init-package-json": {
"version": "0.0.6", "version": "0.0.6",
@ -175,6 +175,9 @@
}, },
"opener": { "opener": {
"version": "1.3.0" "version": "1.3.0"
},
"chmodr": {
"version": "0.1.0"
} }
} }
} }
@ -186,82 +189,82 @@
"underscore": { "underscore": {
"version": "1.3.3" "version": "1.3.3"
}, },
"grainstore": { "windshaft": {
"version": "0.11.2", "version": "0.10.0",
"dependencies": { "dependencies": {
"carto": { "grainstore": {
"version": "0.9.3-cdb3", "version": "0.12.0",
"from": "git://github.com/CartoDB/carto.git#cdb-0.9.3-cdb3",
"dependencies": { "dependencies": {
"mapnik-reference": { "carto": {
"version": "5.0.0-cdb1", "version": "0.9.3-cdb3",
"from": "git://github.com/CartoDB/mapnik-reference.git#cdb-5.0" "from": "git://github.com/CartoDB/carto.git#cdb-0.9.3-cdb3",
},
"xml2js": {
"version": "0.1.14",
"dependencies": { "dependencies": {
"sax": { "mapnik-reference": {
"version": "0.5.2" "version": "5.0.0-cdb1",
"from": "git://github.com/CartoDB/mapnik-reference.git#cdb-5.0"
},
"xml2js": {
"version": "0.1.14",
"dependencies": {
"sax": {
"version": "0.5.2"
}
}
} }
} }
}
}
},
"mapnik-reference": {
"version": "5.0.4"
},
"millstone": {
"version": "0.5.15",
"dependencies": {
"generic-pool": {
"version": "2.0.3"
}, },
"request": { "mapnik-reference": {
"version": "2.12.0", "version": "5.0.4"
},
"millstone": {
"version": "0.5.15",
"dependencies": { "dependencies": {
"form-data": { "generic-pool": {
"version": "0.0.3", "version": "2.0.3"
},
"request": {
"version": "2.12.0",
"dependencies": { "dependencies": {
"combined-stream": { "form-data": {
"version": "0.0.3", "version": "0.0.3",
"dependencies": { "dependencies": {
"delayed-stream": { "combined-stream": {
"version": "0.0.5" "version": "0.0.3",
"dependencies": {
"delayed-stream": {
"version": "0.0.5"
}
}
},
"async": {
"version": "0.1.9"
} }
} }
}, },
"async": { "mime": {
"version": "0.1.9" "version": "1.2.7"
} }
} }
}, },
"srs": {
"version": "0.2.20"
},
"zipfile": {
"version": "0.3.4"
},
"sqlite3": {
"version": "2.1.7"
},
"mime": { "mime": {
"version": "1.2.7" "version": "1.2.9"
},
"mkdirp": {
"version": "0.3.5"
} }
} }
},
"srs": {
"version": "0.2.20"
},
"zipfile": {
"version": "0.3.4"
},
"sqlite3": {
"version": "2.1.7"
},
"mime": {
"version": "1.2.9"
},
"mkdirp": {
"version": "0.3.5"
} }
} }
} },
}
},
"windshaft": {
"version": "0.9.2",
"dependencies": {
"express": { "express": {
"version": "2.5.11", "version": "2.5.11",
"dependencies": { "dependencies": {
@ -269,7 +272,7 @@
"version": "1.9.2", "version": "1.9.2",
"dependencies": { "dependencies": {
"formidable": { "formidable": {
"version": "1.0.12" "version": "1.0.13"
} }
} }
}, },
@ -301,12 +304,18 @@
} }
}, },
"tilelive-mapnik": { "tilelive-mapnik": {
"version": "0.3.3-cdb2", "version": "0.5.0",
"from": "git://github.com/Vizzuality/tilelive-mapnik.git#6061c65a", "from": "git://github.com/Vizzuality/tilelive-mapnik.git#6a360ee50",
"dependencies": { "dependencies": {
"generic-pool": {
"version": "2.0.3"
},
"eio": { "eio": {
"version": "0.1.0" "version": "0.1.0"
}, },
"mime": {
"version": "1.2.9"
},
"sphericalmercator": { "sphericalmercator": {
"version": "1.0.2" "version": "1.0.2"
} }
@ -324,7 +333,12 @@
"version": "0.7.2" "version": "0.7.2"
}, },
"hiredis": { "hiredis": {
"version": "0.1.14" "version": "0.1.15",
"dependencies": {
"bindings": {
"version": "1.1.0"
}
}
}, },
"request": { "request": {
"version": "2.9.202" "version": "2.9.202"
@ -336,7 +350,7 @@
"version": "1.2.2" "version": "1.2.2"
}, },
"semver": { "semver": {
"version": "1.1.3" "version": "1.1.4"
}, },
"mocha": { "mocha": {
"version": "1.2.1", "version": "1.2.1",

View File

@ -1,7 +1,7 @@
{ {
"private": true, "private": true,
"name": "windshaft-cartodb", "name": "windshaft-cartodb",
"version": "1.1.9", "version": "1.2.0",
"description": "A map tile server for CartoDB", "description": "A map tile server for CartoDB",
"url": "https://github.com/Vizzuality/Windshaft-cartodb", "url": "https://github.com/Vizzuality/Windshaft-cartodb",
"licenses": [{ "licenses": [{
@ -21,8 +21,7 @@
"cluster2": "git://github.com/CartoDB/cluster2.git#cdb_production", "cluster2": "git://github.com/CartoDB/cluster2.git#cdb_production",
"node-varnish": "0.1.1", "node-varnish": "0.1.1",
"underscore" : "~1.3.3", "underscore" : "~1.3.3",
"grainstore" : "~0.11.2", "windshaft" : "~0.10.0",
"windshaft" : "~0.9.2",
"step": "0.0.x", "step": "0.0.x",
"generic-pool": "~1.0.12", "generic-pool": "~1.0.12",
"redis": "0.7.2", "redis": "0.7.2",

View File

@ -26,7 +26,7 @@ suite('multilayer', function() {
sqlapi_server = new SQLAPIEmu(global.environment.sqlapi.port, done); sqlapi_server = new SQLAPIEmu(global.environment.sqlapi.port, done);
}); });
test("layergroup with 2 layers, each with its style", function(done) { test("layergroup with 2 layers, each with its style, grid in layer 0", function(done) {
var layergroup = { var layergroup = {
version: '1.0.0', version: '1.0.0',
@ -34,7 +34,8 @@ suite('multilayer', function() {
{ options: { { options: {
sql: 'select cartodb_id, ST_Translate(the_geom_webmercator, 5e6, 0) as the_geom_webmercator from test_table limit 2', sql: 'select cartodb_id, ST_Translate(the_geom_webmercator, 5e6, 0) as the_geom_webmercator from test_table limit 2',
cartocss: '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }', cartocss: '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }',
cartocss_version: '2.0.1' cartocss_version: '2.0.1',
interactivity: [ 'cartodb_id' ]
} }, } },
{ options: { { options: {
sql: 'select cartodb_id, ST_Translate(the_geom_webmercator, -5e6, 0) as the_geom_webmercator from test_table limit 2 offset 2', sql: 'select cartodb_id, ST_Translate(the_geom_webmercator, -5e6, 0) as the_geom_webmercator from test_table limit 2 offset 2',
@ -44,7 +45,7 @@ suite('multilayer', function() {
] ]
}; };
var expected_token = "d442ca6d3ece793b9c16c02a1d1ea5f2"; var expected_token = "9b8b9742efba192ce6c534c83cba0186";
Step( Step(
function do_post() function do_post()
{ {
@ -116,7 +117,7 @@ suite('multilayer', function() {
var next = this; var next = this;
assert.response(server, { assert.response(server, {
url: '/tiles/layergroup/' + expected_token url: '/tiles/layergroup/' + expected_token
+ '/layer0/0/0/0.grid.json?interactivity=cartodb_id', + '/0/0/0.grid.json',
headers: {host: 'localhost' }, headers: {host: 'localhost' },
method: 'GET' method: 'GET'
}, {}, function(res) { }, {}, function(res) {
@ -128,13 +129,118 @@ suite('multilayer', function() {
}); });
}); });
}, },
function finish(err) {
var errors = [];
if ( err ) {
errors.push(err.message);
console.log("Error: " + err);
}
redis_client.keys("map_style|cartodb_test_user_1_db|~" + expected_token, function(err, matches) {
if ( err ) errors.push(err.message);
assert.equal(matches.length, 1, "Missing expected token " + expected_token + " from redis: " + matches);
redis_client.del(matches, function(err) {
if ( err ) errors.push(err.message);
if ( errors.length ) done(new Error(errors));
else done(null);
});
});
}
);
});
test("layergroup with 2 layers, each with its style, grid in layer 1", function(done) {
var layergroup = {
version: '1.0.0',
layers: [
{ options: {
sql: 'select cartodb_id, ST_Translate(the_geom_webmercator, 5e6, 0) as the_geom_webmercator from test_table limit 2',
cartocss: '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }',
cartocss_version: '2.0.1',
interactivity: [ 'fake' ] // unused, not being the topmost
} },
{ options: {
sql: 'select cartodb_id, ST_Translate(the_geom_webmercator, -5e6, 0) as the_geom_webmercator from test_table limit 2 offset 2',
cartocss: '#layer { marker-fill:blue; marker-allow-overlap:true; }',
cartocss_version: '2.0.2',
interactivity: [ 'cartodb_id' ]
} }
]
};
var expected_token = "20c5377296dee4124e6fd2f72309c6eb";
Step(
function do_post()
{
var next = this;
assert.response(server, {
url: '/tiles/layergroup',
method: 'POST',
headers: {host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
var parsedBody = JSON.parse(res.body);
var expectedBody = { layergroupid: expected_token };
// check last modified
var qTables = JSON.stringify({
'q': 'SELECT CDB_QueryTables($windshaft$'
+ layergroup.layers[0].options.sql + ';'
+ layergroup.layers[1].options.sql
+ '$windshaft$)'
});
expectedBody.last_updated = JSON.stringify({
'q': 'SELECT EXTRACT(EPOCH FROM max(updated_at)) as max '
+ 'FROM CDB_TableMetadata m WHERE m.tabname::name = any (\'{'
+ qTables + '}\')'
});
if ( expected_token ) {
//assert.equal(parsedBody.layergroupid, expectedBody.layergroupid);
//assert.equal(parsedBody.last_updated, expectedBody.last_updated);
assert.deepEqual(parsedBody, expectedBody);
}
else expected_token = parsedBody.layergroupid;
next(null, res);
});
},
function do_get_tile(err)
{
if ( err ) throw err;
var next = this;
assert.response(server, {
url: '/tiles/layergroup/' + expected_token + '/0/0/0.png',
method: 'GET',
headers: {host: 'localhost' },
encoding: 'binary'
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "image/png");
// Check X-Cache-Channel
var cc = res.headers['x-cache-channel'];
assert.ok(cc);
var dbname = 'cartodb_test_user_1_db'
assert.equal(cc.substring(0, dbname.length), dbname);
var jsonquery = cc.substring(dbname.length+1);
var sentquery = JSON.parse(jsonquery);
assert.equal(sentquery.q, 'SELECT CDB_QueryTables($windshaft$'
+ layergroup.layers[0].options.sql + ';'
+ layergroup.layers[1].options.sql
+ '$windshaft$)');
assert.imageEqualsFile(res.body, 'test/fixtures/test_table_0_0_0_multilayer1.png', 2,
function(err, similarity) {
next(err);
});
});
},
function do_get_grid_layer1(err) function do_get_grid_layer1(err)
{ {
if ( err ) throw err; if ( err ) throw err;
var next = this; var next = this;
assert.response(server, { assert.response(server, {
url: '/tiles/layergroup/' + expected_token url: '/tiles/layergroup/' + expected_token
+ '/layer1/0/0/0.grid.json?interactivity=cartodb_id', + '/0/0/0.grid.json',
headers: {host: 'localhost' }, headers: {host: 'localhost' },
method: 'GET' method: 'GET'
}, {}, function(res) { }, {}, function(res) {
@ -165,7 +271,6 @@ suite('multilayer', function() {
); );
}); });
test("layergroup can hold substitution tokens", function(done) { test("layergroup can hold substitution tokens", function(done) {
var layergroup = { var layergroup = {
@ -175,12 +280,13 @@ suite('multilayer', function() {
sql: 'select 1 as cartodb_id, ' sql: 'select 1 as cartodb_id, '
+ 'ST_Buffer(!bbox!, -32*greatest(!pixel_width!,!pixel_height!)) as the_geom_webmercator', + 'ST_Buffer(!bbox!, -32*greatest(!pixel_width!,!pixel_height!)) as the_geom_webmercator',
cartocss: '#layer { polygon-fill:red; }', cartocss: '#layer { polygon-fill:red; }',
cartocss_version: '2.0.1' cartocss_version: '2.0.1',
interactivity: ['cartodb_id']
} } } }
] ]
}; };
var expected_token; // = "d442ca6d3ece793b9c16c02a1d1ea5f2"; var expected_token = "71c795a09d5e351c937a0b4bcbd867e5";
Step( Step(
function do_post() function do_post()
{ {
@ -280,7 +386,7 @@ suite('multilayer', function() {
var next = this; var next = this;
assert.response(server, { assert.response(server, {
url: '/tiles/layergroup/' + expected_token url: '/tiles/layergroup/' + expected_token
+ '/layer0/1/0/0.grid.json?interactivity=cartodb_id', + '/1/0/0.grid.json',
headers: {host: 'localhost' }, headers: {host: 'localhost' },
method: 'GET' method: 'GET'
}, {}, function(res) { }, {}, function(res) {
@ -298,7 +404,7 @@ suite('multilayer', function() {
var next = this; var next = this;
assert.response(server, { assert.response(server, {
url: '/tiles/layergroup/' + expected_token url: '/tiles/layergroup/' + expected_token
+ '/layer0/4/0/0.grid.json?interactivity=cartodb_id', + '/4/0/0.grid.json',
headers: {host: 'localhost' }, headers: {host: 'localhost' },
method: 'GET' method: 'GET'
}, {}, function(res) { }, {}, function(res) {