Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.common.document.DocumentField;
import org.elasticsearch.common.geo.GeoBoundingBox;
Expand Down Expand Up @@ -45,6 +46,7 @@
import org.elasticsearch.search.aggregations.metrics.InternalGeoBounds;
import org.elasticsearch.search.aggregations.pipeline.StatsBucketPipelineAggregationBuilder;
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder.MetricsAggregationBuilder;
import org.elasticsearch.search.crossproject.CrossProjectModeDecider;
import org.elasticsearch.search.fetch.subphase.FieldAndFormat;
import org.elasticsearch.search.profile.SearchProfileResults;
import org.elasticsearch.search.sort.SortBuilder;
Expand Down Expand Up @@ -91,10 +93,12 @@ public class RestVectorTileAction extends BaseRestHandler {

private final SearchUsageHolder searchUsageHolder;
private final Settings settings;
private final CrossProjectModeDecider crossProjectModeDecider;

public RestVectorTileAction(SearchUsageHolder searchUsageHolder, Settings settings) {
this.searchUsageHolder = searchUsageHolder;
this.settings = settings;
this.crossProjectModeDecider = new CrossProjectModeDecider(settings);
}

@Override
Expand All @@ -109,15 +113,23 @@ public String getName() {

@Override
protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException {
if (settings != null && settings.getAsBoolean("serverless.cross_project.enabled", false)) {
// accept but drop project_routing param until fully supported
restRequest.param("project_routing");
}
boolean crossProjectEnabled = crossProjectModeDecider.crossProjectEnabled();

// This will allow to cancel the search request if the http channel is closed
final RestCancellableNodeClient cancellableNodeClient = new RestCancellableNodeClient(client, restRequest.getHttpChannel());
final VectorTileRequest request = VectorTileRequest.parseRestRequest(restRequest, searchUsageHolder::updateUsage);
final SearchRequestBuilder searchRequestBuilder = searchRequestBuilder(cancellableNodeClient, request);

if (crossProjectEnabled && request.allowsCrossProject()) {
searchRequestBuilder.setIndicesOptions(
IndicesOptions.builder(searchRequestBuilder.request().indicesOptions())
.crossProjectModeOptions(new IndicesOptions.CrossProjectModeOptions(true))
.build()
);
} else if (crossProjectEnabled == false && request.getProjectRouting() != null) {
throw new IllegalArgumentException("Unknown key for a VALUE_STRING in [project_routing]");
}

return channel -> searchRequestBuilder.execute(new RestResponseListener<>(channel) {

@Override
Expand Down Expand Up @@ -288,10 +300,10 @@ private static SearchRequestBuilder searchRequestBuilder(RestCancellableNodeClie
for (SortBuilder<?> sortBuilder : request.getSortBuilders()) {
searchRequestBuilder.addSort(sortBuilder);
}
searchRequestBuilder.request().setProjectRouting(request.getProjectRouting());
return searchRequestBuilder;
}

@SuppressWarnings("unchecked")
private static VectorTile.Tile.Layer.Builder buildHitsLayer(SearchHit[] hits, VectorTileRequest request, FeatureFactory featureFactory)
throws IOException {
final VectorTile.Tile.Layer.Builder hitsLayerBuilder = VectorTileUtils.createLayerBuilder(HITS_LAYER, request.getExtent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

package org.elasticsearch.xpack.vectortile.rest;

import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.geo.SimpleVectorTileFormatter;
import org.elasticsearch.core.Booleans;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.geometry.Rectangle;
import org.elasticsearch.index.query.AbstractQueryBuilder;
import org.elasticsearch.index.query.GeoShapeQueryBuilder;
Expand Down Expand Up @@ -46,7 +48,7 @@
/**
* Transforms a rest request in a vector tile request
*/
class VectorTileRequest {
class VectorTileRequest implements IndicesRequest.CrossProjectCandidate {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't really need this here since it's the SearchRequest that'll be executing underneath. That said, I say we leave it to indicate that a VT request is CPS-capable. I'm open to discussion(s) on this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Seems fine to me.


protected static final String INDEX_PARAM = "index";
protected static final String FIELD_PARAM = "field";
Expand All @@ -61,6 +63,7 @@ class VectorTileRequest {
protected static final ParseField BUFFER_FIELD = new ParseField("buffer");
protected static final ParseField EXACT_BOUNDS_FIELD = new ParseField("exact_bounds");
protected static final ParseField WITH_LABELS_FIELD = new ParseField("with_labels");
protected static final ParseField PROJECT_ROUTING = new ParseField("project_routing");

protected static class Defaults {
public static final int SIZE = 10000;
Expand Down Expand Up @@ -131,6 +134,7 @@ protected static class Defaults {
return p.intValue();
}
}, SearchSourceBuilder.TRACK_TOTAL_HITS_FIELD, ObjectParser.ValueType.VALUE);
PARSER.declareString(VectorTileRequest::setProjectRouting, PROJECT_ROUTING);
}

static VectorTileRequest parseRestRequest(RestRequest restRequest, Consumer<SearchUsage> searchUsageConsumer) throws IOException {
Expand Down Expand Up @@ -221,6 +225,9 @@ static VectorTileRequest parseRestRequest(RestRequest restRequest, Consumer<Sear
private boolean with_labels = Defaults.WITH_LABELS;
private int trackTotalHitsUpTo = Defaults.TRACK_TOTAL_HITS_UP_TO;

@Nullable
private String projectRouting;

private VectorTileRequest(String[] indexes, String field, int z, int x, int y) {
this.indexes = indexes;
this.field = field;
Expand Down Expand Up @@ -322,6 +329,24 @@ public int getGridPrecision() {
return gridPrecision;
}

@Override
public boolean allowsCrossProject() {
return true;
}

public void setProjectRouting(String projectRouting) {
if (this.projectRouting != null) {
throw new IllegalArgumentException("project_routing is already set to [" + this.projectRouting + "]");
}

this.projectRouting = projectRouting;
}

@Nullable
public String getProjectRouting() {
return this.projectRouting;
}

private void setGridPrecision(int gridPrecision) {
if (gridPrecision < 0) {
throw new IllegalArgumentException("[gridPrecision] parameter cannot be negative, found [" + gridPrecision + "]");
Expand Down