Skip to content

Commit c519b93

Browse files
authored
Make some vector tile body parameters as query parameters (#75522)
Following the same structure of the _search API, this changes makes possible to define some body parameters as query parameters (e.g. defined as URL parameters)
1 parent b9bc7a6 commit c519b93

File tree

3 files changed

+134
-17
lines changed

3 files changed

+134
-17
lines changed

x-pack/plugin/vector-tile/src/javaRestTest/java/org/elasticsearch/xpack/vectortile/VectorTileRestIT.java

Lines changed: 115 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public void deleteData() throws IOException {
159159
}
160160

161161
public void testBasicGet() throws Exception {
162-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
162+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
163163
mvtRequest.setJsonEntity("{\"size\" : 100}");
164164
final VectorTile.Tile tile = execute(mvtRequest);
165165
assertThat(tile.getLayersCount(), Matchers.equalTo(3));
@@ -169,7 +169,7 @@ public void testBasicGet() throws Exception {
169169
}
170170

171171
public void testExtent() throws Exception {
172-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
172+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
173173
mvtRequest.setJsonEntity("{\"size\" : 100, \"extent\" : 256}");
174174
final VectorTile.Tile tile = execute(mvtRequest);
175175
assertThat(tile.getLayersCount(), Matchers.equalTo(3));
@@ -178,17 +178,67 @@ public void testExtent() throws Exception {
178178
assertLayer(tile, META_LAYER, 256, 1, 14);
179179
}
180180

181+
public void testExtentURL() throws Exception {
182+
final Request mvtRequest = new Request(
183+
getHttpMethod(),
184+
INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y + "?extent=" + 512
185+
);
186+
mvtRequest.setJsonEntity("{\"size\" : 100, \"extent\" : 256}");
187+
final VectorTile.Tile tile = execute(mvtRequest);
188+
assertThat(tile.getLayersCount(), Matchers.equalTo(3));
189+
assertLayer(tile, HITS_LAYER, 512, 33, 1);
190+
assertLayer(tile, AGGS_LAYER, 512, 1, 1);
191+
assertLayer(tile, META_LAYER, 512, 1, 14);
192+
}
193+
194+
public void testExactBounds() throws Exception {
195+
{
196+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
197+
mvtRequest.setJsonEntity("{\"size\" : 0, \"grid_precision\" : 0}");
198+
final VectorTile.Tile tile = execute(mvtRequest);
199+
assertThat(tile.getLayersCount(), Matchers.equalTo(1));
200+
assertLayer(tile, META_LAYER, 4096, 1, 8);
201+
final VectorTile.Tile.Layer layer = getLayer(tile, META_LAYER);
202+
assertThat(layer.getFeatures(0).getType(), Matchers.equalTo(VectorTile.Tile.GeomType.POLYGON));
203+
204+
}
205+
{
206+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
207+
mvtRequest.setJsonEntity("{\"size\" : 0, \"grid_precision\" : 0, \"exact_bounds\" : true}");
208+
final VectorTile.Tile tile = execute(mvtRequest);
209+
assertThat(tile.getLayersCount(), Matchers.equalTo(1));
210+
assertLayer(tile, META_LAYER, 4096, 1, 8);
211+
final VectorTile.Tile.Layer layer = getLayer(tile, META_LAYER);
212+
// edge case: because all points are the same, the bounding box is a point and cannot be expressed as a polygon.
213+
// Therefore the feature ends-up without a geometry.
214+
assertThat(layer.getFeatures(0).hasType(), Matchers.equalTo(false));
215+
}
216+
{
217+
final Request mvtRequest = new Request(
218+
getHttpMethod(),
219+
INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y + "?exact_bounds=false"
220+
);
221+
mvtRequest.setJsonEntity("{\"size\" : 0, \"grid_precision\" : 0, \"exact_bounds\" : true}");
222+
final VectorTile.Tile tile = execute(mvtRequest);
223+
assertThat(tile.getLayersCount(), Matchers.equalTo(1));
224+
assertLayer(tile, META_LAYER, 4096, 1, 8);
225+
final VectorTile.Tile.Layer layer = getLayer(tile, META_LAYER);
226+
assertThat(layer.getFeatures(0).getType(), Matchers.equalTo(VectorTile.Tile.GeomType.POLYGON));
227+
228+
}
229+
}
230+
181231
public void testEmpty() throws Exception {
182232
final int newY = (1 << z) - 1 == y ? y - 1 : y + 1;
183-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + newY);
233+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + newY);
184234
final VectorTile.Tile tile = execute(mvtRequest);
185235
assertThat(tile.getLayersCount(), Matchers.equalTo(1));
186236
assertLayer(tile, META_LAYER, 4096, 1, 10);
187237
}
188238

189239
public void testGridPrecision() throws Exception {
190240
{
191-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
241+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
192242
mvtRequest.setJsonEntity("{\"size\" : 100, \"grid_precision\": 7 }");
193243
final VectorTile.Tile tile = execute(mvtRequest);
194244
assertThat(tile.getLayersCount(), Matchers.equalTo(3));
@@ -197,7 +247,7 @@ public void testGridPrecision() throws Exception {
197247
assertLayer(tile, META_LAYER, 4096, 1, 14);
198248
}
199249
{
200-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
250+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
201251
mvtRequest.setJsonEntity("{\"grid_precision\": 9 }");
202252
final ResponseException ex = expectThrows(ResponseException.class, () -> execute(mvtRequest));
203253
assertThat(ex.getResponse().getStatusLine().getStatusCode(), Matchers.equalTo(HttpStatus.SC_BAD_REQUEST));
@@ -206,49 +256,86 @@ public void testGridPrecision() throws Exception {
206256

207257
public void testGridType() throws Exception {
208258
{
209-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
259+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
210260
mvtRequest.setJsonEntity("{\"size\" : 100, \"grid_type\": \"point\" }");
211261
final VectorTile.Tile tile = execute(mvtRequest);
212262
assertThat(tile.getLayersCount(), Matchers.equalTo(3));
213263
assertLayer(tile, HITS_LAYER, 4096, 33, 1);
214264
assertLayer(tile, AGGS_LAYER, 4096, 1, 1);
215265
assertLayer(tile, META_LAYER, 4096, 1, 14);
266+
assertFeatureType(tile, AGGS_LAYER, VectorTile.Tile.GeomType.POINT);
216267
}
217268
{
218-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
269+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
219270
mvtRequest.setJsonEntity("{\"size\" : 100, \"grid_type\": \"grid\" }");
220271
final VectorTile.Tile tile = execute(mvtRequest);
221272
assertThat(tile.getLayersCount(), Matchers.equalTo(3));
222273
assertLayer(tile, HITS_LAYER, 4096, 33, 1);
223274
assertLayer(tile, AGGS_LAYER, 4096, 1, 1);
224275
assertLayer(tile, META_LAYER, 4096, 1, 14);
276+
assertFeatureType(tile, AGGS_LAYER, VectorTile.Tile.GeomType.POLYGON);
225277
}
226278
{
227-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
279+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
228280
mvtRequest.setJsonEntity("{\"grid_type\": \"invalid_type\" }");
229281
final ResponseException ex = expectThrows(ResponseException.class, () -> execute(mvtRequest));
230282
assertThat(ex.getResponse().getStatusLine().getStatusCode(), Matchers.equalTo(HttpStatus.SC_BAD_REQUEST));
231283
}
232284
}
233285

286+
public void testGridTypeURL() throws Exception {
287+
final Request mvtRequest = new Request(
288+
getHttpMethod(),
289+
INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y + "?grid_type=grid"
290+
);
291+
mvtRequest.setJsonEntity("{\"size\" : 100, \"grid_type\": \"point\" }");
292+
final VectorTile.Tile tile = execute(mvtRequest);
293+
assertThat(tile.getLayersCount(), Matchers.equalTo(3));
294+
assertLayer(tile, HITS_LAYER, 4096, 33, 1);
295+
assertLayer(tile, AGGS_LAYER, 4096, 1, 1);
296+
assertLayer(tile, META_LAYER, 4096, 1, 14);
297+
assertFeatureType(tile, AGGS_LAYER, VectorTile.Tile.GeomType.POLYGON);
298+
}
299+
234300
public void testNoAggLayer() throws Exception {
235-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
301+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
236302
mvtRequest.setJsonEntity("{\"size\" : 100, \"grid_precision\": 0 }");
237303
final VectorTile.Tile tile = execute(mvtRequest);
238304
assertThat(tile.getLayersCount(), Matchers.equalTo(2));
239305
assertLayer(tile, HITS_LAYER, 4096, 33, 1);
240306
assertLayer(tile, META_LAYER, 4096, 1, 9);
241307
}
242308

309+
public void testNoAggLayerURL() throws Exception {
310+
final Request mvtRequest = new Request(
311+
getHttpMethod(),
312+
INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y + "?grid_precision=" + 0
313+
);
314+
mvtRequest.setJsonEntity("{\"size\" : 100, \"grid_precision\": 4 }");
315+
final VectorTile.Tile tile = execute(mvtRequest);
316+
assertThat(tile.getLayersCount(), Matchers.equalTo(2));
317+
assertLayer(tile, HITS_LAYER, 4096, 33, 1);
318+
assertLayer(tile, META_LAYER, 4096, 1, 9);
319+
}
320+
243321
public void testNoHitsLayer() throws Exception {
244-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
322+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
245323
mvtRequest.setJsonEntity("{\"size\": 0 }");
246324
final VectorTile.Tile tile = execute(mvtRequest);
247325
assertThat(tile.getLayersCount(), Matchers.equalTo(2));
248326
assertLayer(tile, AGGS_LAYER, 4096, 1, 1);
249327
assertLayer(tile, META_LAYER, 4096, 1, 13);
250328
}
251329

330+
public void testNoHitsLayerURL() throws Exception {
331+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y + "?size=" + 0);
332+
mvtRequest.setJsonEntity("{\"size\": 100 }");
333+
final VectorTile.Tile tile = execute(mvtRequest);
334+
assertThat(tile.getLayersCount(), Matchers.equalTo(2));
335+
assertLayer(tile, AGGS_LAYER, 4096, 1, 1);
336+
assertLayer(tile, META_LAYER, 4096, 1, 13);
337+
}
338+
252339
public void testRuntimeFieldWithSort() throws Exception {
253340
String runtimeMapping = "\"runtime_mappings\": {\n"
254341
+ " \"width\": {\n"
@@ -259,7 +346,7 @@ public void testRuntimeFieldWithSort() throws Exception {
259346
+ "}\n";
260347
{
261348
// desc order, polygon should be the first hit
262-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_ALL + "/_mvt/location/" + z + "/" + x + "/" + y);
349+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_ALL + "/_mvt/location/" + z + "/" + x + "/" + y);
263350
mvtRequest.setJsonEntity(
264351
"{\n"
265352
+ " \"size\" : 100,\n"
@@ -285,7 +372,7 @@ public void testRuntimeFieldWithSort() throws Exception {
285372
}
286373
{
287374
// asc order, polygon should be the last hit
288-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_ALL + "/_mvt/location/" + z + "/" + x + "/" + y);
375+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_ALL + "/_mvt/location/" + z + "/" + x + "/" + y);
289376
mvtRequest.setJsonEntity(
290377
"{\n"
291378
+ " \"size\" : 100,\n"
@@ -312,7 +399,7 @@ public void testRuntimeFieldWithSort() throws Exception {
312399
}
313400

314401
public void testBasicQueryGet() throws Exception {
315-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
402+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_POINTS + "/_mvt/location/" + z + "/" + x + "/" + y);
316403
mvtRequest.setJsonEntity(
317404
"{\n"
318405
+ " \"query\": {\n"
@@ -332,7 +419,7 @@ public void testBasicQueryGet() throws Exception {
332419
}
333420

334421
public void testBasicShape() throws Exception {
335-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_SHAPES + "/_mvt/location/" + z + "/" + x + "/" + y);
422+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_SHAPES + "/_mvt/location/" + z + "/" + x + "/" + y);
336423
final VectorTile.Tile tile = execute(mvtRequest);
337424
assertThat(tile.getLayersCount(), Matchers.equalTo(3));
338425
assertLayer(tile, HITS_LAYER, 4096, 1, 1);
@@ -341,7 +428,7 @@ public void testBasicShape() throws Exception {
341428
}
342429

343430
public void testWithFields() throws Exception {
344-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_SHAPES + "/_mvt/location/" + z + "/" + x + "/" + y);
431+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_SHAPES + "/_mvt/location/" + z + "/" + x + "/" + y);
345432
mvtRequest.setJsonEntity("{\"fields\": [\"name\", \"value1\"] }");
346433
final VectorTile.Tile tile = execute(mvtRequest);
347434
assertThat(tile.getLayersCount(), Matchers.equalTo(3));
@@ -351,7 +438,7 @@ public void testWithFields() throws Exception {
351438
}
352439

353440
public void testMinAgg() throws Exception {
354-
final Request mvtRequest = new Request(HttpGet.METHOD_NAME, INDEX_SHAPES + "/_mvt/location/" + z + "/" + x + "/" + y);
441+
final Request mvtRequest = new Request(getHttpMethod(), INDEX_SHAPES + "/_mvt/location/" + z + "/" + x + "/" + y);
355442
mvtRequest.setJsonEntity(
356443
"{\n"
357444
+ " \"aggs\": {\n"
@@ -370,6 +457,18 @@ public void testMinAgg() throws Exception {
370457
assertLayer(tile, META_LAYER, 4096, 1, 19);
371458
}
372459

460+
private String getHttpMethod() {
461+
return random().nextBoolean() ? HttpGet.METHOD_NAME : HttpPost.METHOD_NAME;
462+
}
463+
464+
private void assertFeatureType(VectorTile.Tile tile, String name, VectorTile.Tile.GeomType type) {
465+
final VectorTile.Tile.Layer layer = getLayer(tile, name);
466+
for (int i = 0; i < layer.getFeaturesCount(); i++) {
467+
final VectorTile.Tile.Feature feature = layer.getFeatures(i);
468+
assertThat(feature.getType(), Matchers.equalTo(type));
469+
}
470+
}
471+
373472
private void assertLayer(VectorTile.Tile tile, String name, int extent, int numFeatures, int numTags) {
374473
final VectorTile.Tile.Layer layer = getLayer(tile, name);
375474
assertThat(layer.getExtent(), Matchers.equalTo(extent));

x-pack/plugin/vector-tile/src/main/java/org/elasticsearch/xpack/vectortile/rest/RestVectorTileAction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import java.util.stream.Collectors;
5959

6060
import static org.elasticsearch.rest.RestRequest.Method.GET;
61+
import static org.elasticsearch.rest.RestRequest.Method.POST;
6162

6263
/**
6364
* Main class handling a call to the _mvt API.
@@ -81,7 +82,7 @@ public RestVectorTileAction() {}
8182

8283
@Override
8384
public List<Route> routes() {
84-
return List.of(new Route(GET, "{index}/_mvt/{field}/{z}/{x}/{y}"));
85+
return List.of(new Route(GET, "{index}/_mvt/{field}/{z}/{x}/{y}"), new Route(POST, "{index}/_mvt/{field}/{z}/{x}/{y}"));
8586
}
8687

8788
@Override

x-pack/plugin/vector-tile/src/main/java/org/elasticsearch/xpack/vectortile/rest/VectorTileRequest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,23 @@ static VectorTileRequest parseRestRequest(RestRequest restRequest) throws IOExce
141141
PARSER.parse(contentParser, request, restRequest);
142142
}
143143
}
144+
// Following the same strategy of the _search API, some parameters can be defined in the body or as URL parameters.
145+
// URL parameters takes precedence so we check them here.
146+
if (restRequest.hasParam(SearchSourceBuilder.SIZE_FIELD.getPreferredName())) {
147+
request.setSize(restRequest.paramAsInt(SearchSourceBuilder.SIZE_FIELD.getPreferredName(), Defaults.SIZE));
148+
}
149+
if (restRequest.hasParam(GRID_PRECISION_FIELD.getPreferredName())) {
150+
request.setGridPrecision(restRequest.paramAsInt(GRID_PRECISION_FIELD.getPreferredName(), Defaults.GRID_PRECISION));
151+
}
152+
if (restRequest.hasParam(EXTENT_FIELD.getPreferredName())) {
153+
request.setExtent(restRequest.paramAsInt(EXTENT_FIELD.getPreferredName(), Defaults.EXTENT));
154+
}
155+
if (restRequest.hasParam(GRID_TYPE_FIELD.getPreferredName())) {
156+
request.setGridType(restRequest.param(GRID_TYPE_FIELD.getPreferredName(), Defaults.GRID_TYPE.name()));
157+
}
158+
if (restRequest.hasParam(EXACT_BOUNDS_FIELD.getPreferredName())) {
159+
request.setExactBounds(restRequest.paramAsBoolean(EXACT_BOUNDS_FIELD.getPreferredName(), Defaults.EXACT_BOUNDS));
160+
}
144161
return request;
145162
}
146163

0 commit comments

Comments
 (0)