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 @@ -55,7 +55,6 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC
final OpenPointInTimeRequest openRequest = new OpenPointInTimeRequest(indices);
final boolean crossProjectEnabled = crossProjectModeDecider.crossProjectEnabled();
if (crossProjectEnabled) {
openRequest.projectRouting(request.param("project_routing", null));
openRequest.indicesOptions(IndicesOptions.fromRequest(request, OpenPointInTimeRequest.DEFAULT_CPS_INDICES_OPTIONS));
} else {
openRequest.indicesOptions(IndicesOptions.fromRequest(request, OpenPointInTimeRequest.DEFAULT_INDICES_OPTIONS));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC

final boolean crossProjectEnabled = crossProjectModeDecider.crossProjectEnabled();
if (crossProjectEnabled) {
fieldRequest.projectRouting(request.param("project_routing", null));
// Setting includeResolvedTo to always include index resolution data structure in the linked project responses,
// in order to allow the coordinating node to call CrossProjectIndexResolutionValidator#validate
fieldRequest.includeResolvedTo(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@

package org.elasticsearch.rest.action.admin.indices;

import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.admin.indices.resolve.ResolveIndexAction;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexMode;
Expand All @@ -20,22 +22,26 @@
import org.elasticsearch.rest.Scope;
import org.elasticsearch.rest.ServerlessScope;
import org.elasticsearch.rest.action.RestToXContentListener;
import org.elasticsearch.search.crossproject.CrossProjectModeDecider;
import org.elasticsearch.xcontent.XContentParser;

import java.io.IOException;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;

import static org.elasticsearch.rest.RestRequest.Method.GET;
import static org.elasticsearch.rest.RestRequest.Method.POST;

@ServerlessScope(Scope.PUBLIC)
public class RestResolveIndexAction extends BaseRestHandler {
private static final Set<String> CAPABILITIES = Set.of("mode_filter");
private final Settings settings;
private final CrossProjectModeDecider crossProjectModeDecider;

public RestResolveIndexAction(Settings settings) {
this.settings = settings;
this.crossProjectModeDecider = new CrossProjectModeDecider(settings);
}

@Override
Expand All @@ -45,7 +51,7 @@ public String getName() {

@Override
public List<Route> routes() {
return List.of(new Route(GET, "/_resolve/index/{name}"));
return List.of(new Route(GET, "/_resolve/index/{name}"), new Route(POST, "/_resolve/index/{name}"));
}

@Override
Expand All @@ -57,17 +63,28 @@ public Set<String> supportedCapabilities() {
protected BaseRestHandler.RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
String[] indices = Strings.splitStringByCommaToArray(request.param("name"));
String modeParam = request.param("mode");
final boolean crossProjectEnabled = settings != null && settings.getAsBoolean("serverless.cross_project.enabled", false);
String projectRouting = null;
if (crossProjectEnabled) {
projectRouting = request.param("project_routing");
}

final boolean crossProjectEnabled = crossProjectModeDecider.crossProjectEnabled();
AtomicReference<String> projectRouting = new AtomicReference<>();
IndicesOptions indicesOptions = IndicesOptions.fromRequest(request, ResolveIndexAction.Request.DEFAULT_INDICES_OPTIONS);

if (crossProjectEnabled) {
request.withContentOrSourceParamParserOrNull(parser -> {
try {
// If parser is null, there's no request body. projectRouting will then yield `null`.
if (parser != null) {
projectRouting.set(parseProjectRouting(parser));
}
} catch (Exception e) {
throw new ElasticsearchException("Couldn't parse request body", e);
}
});

indicesOptions = IndicesOptions.builder(indicesOptions)
.crossProjectModeOptions(new IndicesOptions.CrossProjectModeOptions(true))
.build();
}

ResolveIndexAction.Request resolveRequest = new ResolveIndexAction.Request(
indices,
indicesOptions,
Expand All @@ -76,8 +93,44 @@ protected BaseRestHandler.RestChannelConsumer prepareRequest(RestRequest request
: Arrays.stream(modeParam.split(","))
.map(IndexMode::fromString)
.collect(() -> EnumSet.noneOf(IndexMode.class), EnumSet::add, EnumSet::addAll),
projectRouting
projectRouting.get()
);
return channel -> client.admin().indices().resolveIndex(resolveRequest, new RestToXContentListener<>(channel));
}

private static String parseProjectRouting(XContentParser parser) throws ParsingException {
try {
XContentParser.Token first = parser.nextToken();
if (first == null) {
return null;
}

if (first != XContentParser.Token.START_OBJECT) {
throw new ParsingException(
parser.getTokenLocation(),
"Expected [" + XContentParser.Token.START_OBJECT + "] but found [" + first + "]",
parser.getTokenLocation()
);
}

String projectRouting = null;
for (XContentParser.Token token = parser.nextToken(); token != XContentParser.Token.END_OBJECT; token = parser.nextToken()) {
if (token == XContentParser.Token.FIELD_NAME) {
String currentName = parser.currentName();
if ("project_routing".equals(currentName)) {
parser.nextToken();
projectRouting = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "request does not support [" + parser.currentName() + "]");
}
}
}

return projectRouting;
} catch (ParsingException e) {
throw e;
} catch (Exception e) {
throw new ParsingException(parser == null ? null : parser.getTokenLocation(), "Failed to parse", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,6 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC
request.param("min_compatible_shard_node");

final boolean crossProjectEnabled = crossProjectModeDecider.crossProjectEnabled();
if (crossProjectEnabled) {
searchRequest.setProjectRouting(request.param("project_routing"));
}

/*
* We have to pull out the call to `source().size(size)` because
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
boolean crossProjectEnabled = crossProjectModeDecider.crossProjectEnabled();
if (crossProjectEnabled) {
submit.getSearchRequest().setCcsMinimizeRoundtrips(true);
submit.getSearchRequest().setProjectRouting(request.param("project_routing"));
}

IntConsumer setSize = size -> submit.getSearchRequest().source().size(size);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
indicesOptions = IndicesOptions.builder(indicesOptions)
.crossProjectModeOptions(new IndicesOptions.CrossProjectModeOptions(true))
.build();
eqlRequest.projectRouting(request.param("project_routing"));
}
eqlRequest.indicesOptions(indicesOptions);
if (request.hasParam("wait_for_completion_timeout")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,6 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
sqlRequest = SqlQueryRequest.fromXContent(parser);
}

String routingParam = request.param("project_routing");
if (routingParam != null) {
// takes precedence on the parameter in the body
sqlRequest.projectRouting(routingParam);
}
if (sqlRequest.projectRouting() != null && crossProjectModeDecider.crossProjectEnabled() == false) {
throw new InvalidArgumentException("[project_routing] is only allowed when cross-project search is enabled");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
try (XContentParser parser = request.contentOrSourceParamParser()) {
sqlRequest = SqlTranslateRequest.fromXContent(parser);
}
String routingParam = request.param("project_routing");
if (routingParam != null) {
// takes precedence on the parameter in the body
sqlRequest.projectRouting(routingParam);
}
if (sqlRequest.projectRouting() != null && crossProjectModeDecider.crossProjectEnabled() == false) {
throw new InvalidArgumentException("[project_routing] is only allowed when cross-project search is enabled");
}
Expand Down