Skip to content

Commit cc3191b

Browse files
authored
Add to SearchUsages queries generated by the vector tiles API (elastic#113449) (elastic#113475)
Register the queries used via the vector tiles API in SearchUsages.
1 parent 24c15ab commit cc3191b

File tree

5 files changed

+40
-14
lines changed

5 files changed

+40
-14
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@
2525
import org.elasticsearch.geometry.Polygon;
2626
import org.elasticsearch.geometry.Rectangle;
2727
import org.elasticsearch.geometry.utils.WellKnownText;
28+
import org.elasticsearch.index.query.GeoShapeQueryBuilder;
29+
import org.elasticsearch.index.query.TermQueryBuilder;
2830
import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils;
2931
import org.elasticsearch.test.rest.ESRestTestCase;
32+
import org.elasticsearch.test.rest.ObjectPath;
3033
import org.hamcrest.Matchers;
3134
import org.junit.AfterClass;
3235
import org.junit.Before;
@@ -790,7 +793,9 @@ public void testBasicQueryGet() throws Exception {
790793
}
791794
}
792795
}""");
796+
final int termsUsage = queryUsage(TermQueryBuilder.NAME);
793797
final VectorTile.Tile tile = execute(mvtRequest);
798+
assertThat(queryUsage(TermQueryBuilder.NAME), Matchers.equalTo(termsUsage + 1));
794799
assertThat(tile.getLayersCount(), Matchers.equalTo(3));
795800
assertLayer(tile, HITS_LAYER, 4096, 1, 2);
796801
assertLayer(tile, AGGS_LAYER, 4096, 1, 2);
@@ -1060,12 +1065,21 @@ private void assertBucketKeyTag(VectorTile.Tile.Layer layer, VectorTile.Tile.Fea
10601065
}
10611066

10621067
private VectorTile.Tile execute(Request mvtRequest) throws IOException {
1068+
final int geoShapeUsage = queryUsage(GeoShapeQueryBuilder.NAME);
10631069
final Response response = client().performRequest(mvtRequest);
1070+
assertThat(queryUsage(GeoShapeQueryBuilder.NAME), Matchers.equalTo(geoShapeUsage + 1));
10641071
final InputStream inputStream = response.getEntity().getContent();
10651072
assertThat(response.getStatusLine().getStatusCode(), Matchers.equalTo(HttpStatus.SC_OK));
10661073
return VectorTile.Tile.parseFrom(inputStream);
10671074
}
10681075

1076+
private int queryUsage(String queryName) throws IOException {
1077+
final Request request = new Request(HttpGet.METHOD_NAME, "/_cluster/stats?filter_path=indices.search.queries." + queryName);
1078+
ObjectPath objectPath = ObjectPath.createFromResponse(client().performRequest(request));
1079+
Integer count = objectPath.evaluate("indices.search.queries." + queryName);
1080+
return count == null ? 0 : count;
1081+
}
1082+
10691083
private VectorTile.Tile.Layer getLayer(VectorTile.Tile tile, String layerName) {
10701084
for (int i = 0; i < tile.getLayersCount(); i++) {
10711085
final VectorTile.Tile.Layer layer = tile.getLayers(i);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,6 @@ public List<RestHandler> getRestHandlers(
4545
Supplier<DiscoveryNodes> nodesInCluster,
4646
Predicate<NodeFeature> clusterSupportsFeature
4747
) {
48-
return List.of(new RestVectorTileAction());
48+
return List.of(new RestVectorTileAction(restController.getSearchUsageHolder()));
4949
}
5050
}

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.elasticsearch.search.fetch.subphase.FieldAndFormat;
4848
import org.elasticsearch.search.profile.SearchProfileResults;
4949
import org.elasticsearch.search.sort.SortBuilder;
50+
import org.elasticsearch.usage.SearchUsageHolder;
5051
import org.elasticsearch.xpack.vectortile.feature.FeatureFactory;
5152

5253
import java.io.IOException;
@@ -87,7 +88,11 @@ public class RestVectorTileAction extends BaseRestHandler {
8788
// internal label position runtime field name
8889
static final String LABEL_POSITION_FIELD_NAME = INTERNAL_AGG_PREFIX + "label_position";
8990

90-
public RestVectorTileAction() {}
91+
private final SearchUsageHolder searchUsageHolder;
92+
93+
public RestVectorTileAction(SearchUsageHolder searchUsageHolder) {
94+
this.searchUsageHolder = searchUsageHolder;
95+
}
9196

9297
@Override
9398
public List<Route> routes() {
@@ -103,7 +108,7 @@ public String getName() {
103108
protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException {
104109
// This will allow to cancel the search request if the http channel is closed
105110
final RestCancellableNodeClient cancellableNodeClient = new RestCancellableNodeClient(client, restRequest.getHttpChannel());
106-
final VectorTileRequest request = VectorTileRequest.parseRestRequest(restRequest);
111+
final VectorTileRequest request = VectorTileRequest.parseRestRequest(restRequest, searchUsageHolder::updateUsage);
107112
final SearchRequestBuilder searchRequestBuilder = searchRequestBuilder(cancellableNodeClient, request);
108113
return channel -> searchRequestBuilder.execute(new RestResponseListener<>(channel) {
109114

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.elasticsearch.core.Booleans;
1313
import org.elasticsearch.geometry.Rectangle;
1414
import org.elasticsearch.index.query.AbstractQueryBuilder;
15+
import org.elasticsearch.index.query.GeoShapeQueryBuilder;
1516
import org.elasticsearch.index.query.QueryBuilder;
1617
import org.elasticsearch.rest.RestRequest;
1718
import org.elasticsearch.script.Script;
@@ -25,6 +26,7 @@
2526
import org.elasticsearch.search.sort.ScriptSortBuilder;
2627
import org.elasticsearch.search.sort.SortBuilder;
2728
import org.elasticsearch.search.sort.SortOrder;
29+
import org.elasticsearch.usage.SearchUsage;
2830
import org.elasticsearch.xcontent.ObjectParser;
2931
import org.elasticsearch.xcontent.ParseField;
3032
import org.elasticsearch.xcontent.XContentParser;
@@ -33,6 +35,7 @@
3335
import java.util.ArrayList;
3436
import java.util.List;
3537
import java.util.Map;
38+
import java.util.function.Consumer;
3639

3740
import static java.util.Collections.emptyList;
3841
import static java.util.Collections.emptyMap;
@@ -75,7 +78,7 @@ protected static class Defaults {
7578
public static final int TRACK_TOTAL_HITS_UP_TO = DEFAULT_TRACK_TOTAL_HITS_UP_TO;
7679
}
7780

78-
private static final ObjectParser<VectorTileRequest, RestRequest> PARSER;
81+
private static final ObjectParser<VectorTileRequest, SearchUsage> PARSER;
7982

8083
static {
8184
PARSER = new ObjectParser<>("vector-tile");
@@ -89,7 +92,7 @@ protected static class Defaults {
8992
}, SearchSourceBuilder.FETCH_FIELDS_FIELD, ObjectParser.ValueType.OBJECT_ARRAY);
9093
PARSER.declareField(
9194
VectorTileRequest::setQueryBuilder,
92-
(p, c) -> AbstractQueryBuilder.parseTopLevelQuery(p),
95+
(p, c) -> AbstractQueryBuilder.parseTopLevelQuery(p, c::trackQueryUsage),
9396
SearchSourceBuilder.QUERY_FIELD,
9497
ObjectParser.ValueType.OBJECT
9598
);
@@ -130,19 +133,23 @@ protected static class Defaults {
130133
}, SearchSourceBuilder.TRACK_TOTAL_HITS_FIELD, ObjectParser.ValueType.VALUE);
131134
}
132135

133-
static VectorTileRequest parseRestRequest(RestRequest restRequest) throws IOException {
136+
static VectorTileRequest parseRestRequest(RestRequest restRequest, Consumer<SearchUsage> searchUsageConsumer) throws IOException {
134137
final VectorTileRequest request = new VectorTileRequest(
135138
Strings.splitStringByCommaToArray(restRequest.param(INDEX_PARAM)),
136139
restRequest.param(FIELD_PARAM),
137140
Integer.parseInt(restRequest.param(Z_PARAM)),
138141
Integer.parseInt(restRequest.param(X_PARAM)),
139142
Integer.parseInt(restRequest.param(Y_PARAM))
140143
);
144+
final SearchUsage searchUsage = new SearchUsage();
141145
if (restRequest.hasContentOrSourceParam()) {
142146
try (XContentParser contentParser = restRequest.contentOrSourceParamParser()) {
143-
PARSER.parse(contentParser, request, restRequest);
147+
PARSER.parse(contentParser, request, searchUsage);
144148
}
145149
}
150+
// The API generates a query on the fly that we track here.
151+
searchUsage.trackQueryUsage(GeoShapeQueryBuilder.NAME);
152+
searchUsageConsumer.accept(searchUsage);
146153
// Following the same strategy of the _search API, some parameters can be defined in the body or as URL parameters.
147154
// URL parameters takes precedence so we check them here.
148155
if (restRequest.hasParam(SearchSourceBuilder.SIZE_FIELD.getPreferredName())) {

x-pack/plugin/vector-tile/src/test/java/org/elasticsearch/xpack/vectortile/rest/VectorTileRequestTests.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public void testWrongTile() {
231231
final FakeRestRequest request = getBasicRequestBuilder(index, field, z, x, y).build();
232232
final IllegalArgumentException ex = expectThrows(
233233
IllegalArgumentException.class,
234-
() -> VectorTileRequest.parseRestRequest(request)
234+
() -> VectorTileRequest.parseRestRequest(request, s -> {})
235235
);
236236
assertThat(ex.getMessage(), Matchers.equalTo("Invalid geotile_grid precision of " + z + ". Must be between 0 and 29."));
237237
}
@@ -243,7 +243,7 @@ public void testWrongTile() {
243243
final FakeRestRequest request = getBasicRequestBuilder(index, field, z, x, y).build();
244244
final IllegalArgumentException ex = expectThrows(
245245
IllegalArgumentException.class,
246-
() -> VectorTileRequest.parseRestRequest(request)
246+
() -> VectorTileRequest.parseRestRequest(request, s -> {})
247247
);
248248
assertThat(ex.getMessage(), Matchers.equalTo("Invalid geotile_grid precision of " + z + ". Must be between 0 and 29."));
249249
}
@@ -255,7 +255,7 @@ public void testWrongTile() {
255255
final FakeRestRequest request = getBasicRequestBuilder(index, field, z, x, y).build();
256256
final IllegalArgumentException ex = expectThrows(
257257
IllegalArgumentException.class,
258-
() -> VectorTileRequest.parseRestRequest(request)
258+
() -> VectorTileRequest.parseRestRequest(request, s -> {})
259259
);
260260
assertThat(ex.getMessage(), Matchers.equalTo("Zoom/X/Y combination is not valid: " + z + "/" + x + "/" + y));
261261
}
@@ -267,7 +267,7 @@ public void testWrongTile() {
267267
final FakeRestRequest request = getBasicRequestBuilder(index, field, z, x, y).build();
268268
final IllegalArgumentException ex = expectThrows(
269269
IllegalArgumentException.class,
270-
() -> VectorTileRequest.parseRestRequest(request)
270+
() -> VectorTileRequest.parseRestRequest(request, s -> {})
271271
);
272272
assertThat(ex.getMessage(), Matchers.equalTo("Zoom/X/Y combination is not valid: " + z + "/" + x + "/" + y));
273273
}
@@ -279,7 +279,7 @@ public void testWrongTile() {
279279
final FakeRestRequest request = getBasicRequestBuilder(index, field, z, x, y).build();
280280
final IllegalArgumentException ex = expectThrows(
281281
IllegalArgumentException.class,
282-
() -> VectorTileRequest.parseRestRequest(request)
282+
() -> VectorTileRequest.parseRestRequest(request, s -> {})
283283
);
284284
assertThat(ex.getMessage(), Matchers.equalTo("Zoom/X/Y combination is not valid: " + z + "/" + x + "/" + y));
285285
}
@@ -291,7 +291,7 @@ public void testWrongTile() {
291291
final FakeRestRequest request = getBasicRequestBuilder(index, field, z, x, y).build();
292292
final IllegalArgumentException ex = expectThrows(
293293
IllegalArgumentException.class,
294-
() -> VectorTileRequest.parseRestRequest(request)
294+
() -> VectorTileRequest.parseRestRequest(request, s -> {})
295295
);
296296
assertThat(ex.getMessage(), Matchers.equalTo("Zoom/X/Y combination is not valid: " + z + "/" + x + "/" + y));
297297
}
@@ -310,7 +310,7 @@ private void assertRestRequest(CheckedConsumer<XContentBuilder, IOException> con
310310
consumer.accept(builder);
311311
builder.endObject();
312312
final FakeRestRequest request = requestBuilder.withContent(BytesReference.bytes(builder), builder.contentType()).build();
313-
final VectorTileRequest vectorTileRequest = VectorTileRequest.parseRestRequest(request);
313+
final VectorTileRequest vectorTileRequest = VectorTileRequest.parseRestRequest(request, s -> {});
314314
assertThat(vectorTileRequest.getIndexes(), Matchers.equalTo(new String[] { index }));
315315
assertThat(vectorTileRequest.getField(), Matchers.equalTo(field));
316316
assertThat(vectorTileRequest.getZ(), Matchers.equalTo(z));

0 commit comments

Comments
 (0)