Skip to content

Commit c2a3ab6

Browse files
SQL: add project_routing option (#138718)
1 parent f9ef2c0 commit c2a3ab6

File tree

16 files changed

+84
-19
lines changed

16 files changed

+84
-19
lines changed

docs/changelog/138718.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 138718
2+
summary: Add `project_routing` option
3+
area: SQL
4+
type: enhancement
5+
issues: []

x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/AbstractSqlQueryRequest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import static org.elasticsearch.xpack.sql.action.Protocol.REQUEST_TIMEOUT_NAME;
5959
import static org.elasticsearch.xpack.sql.action.Protocol.TIME_ZONE_NAME;
6060
import static org.elasticsearch.xpack.sql.action.Protocol.VERSION_NAME;
61+
import static org.elasticsearch.xpack.sql.proto.CoreProtocol.PROJECT_ROUTING_NAME;
6162

6263
/**
6364
* Base class for requests that contain sql queries (Query and Translate)
@@ -91,6 +92,7 @@ public abstract class AbstractSqlQueryRequest extends AbstractSqlRequest impleme
9192
private QueryBuilder filter = null;
9293
private List<SqlTypedParamValue> params = emptyList();
9394
private Map<String, Object> runtimeMappings = emptyMap();
95+
private String projectRouting;
9496

9597
static final ParseField QUERY = new ParseField(QUERY_NAME);
9698
static final ParseField CURSOR = new ParseField(CURSOR_NAME);
@@ -104,6 +106,7 @@ public abstract class AbstractSqlQueryRequest extends AbstractSqlRequest impleme
104106
static final ParseField MODE = new ParseField(MODE_NAME);
105107
static final ParseField CLIENT_ID = new ParseField(CLIENT_ID_NAME);
106108
static final ParseField VERSION = new ParseField(VERSION_NAME);
109+
static final ParseField PROJECT_ROUTING = new ParseField(PROJECT_ROUTING_NAME);
107110

108111
public AbstractSqlQueryRequest() {
109112
super();
@@ -155,6 +158,7 @@ protected static <R extends AbstractSqlQueryRequest> ObjectParser<R, Void> objec
155158
);
156159
parser.declareObject(AbstractSqlQueryRequest::filter, (p, c) -> AbstractQueryBuilder.parseTopLevelQuery(p), FILTER);
157160
parser.declareObject(AbstractSqlQueryRequest::runtimeMappings, (p, c) -> p.map(), SearchSourceBuilder.RUNTIME_MAPPINGS_FIELD);
161+
parser.declareString(AbstractSqlQueryRequest::projectRouting, PROJECT_ROUTING);
158162
return parser;
159163
}
160164

@@ -423,6 +427,14 @@ public AbstractSqlQueryRequest runtimeMappings(Map<String, Object> runtimeMappin
423427
return this;
424428
}
425429

430+
public String projectRouting() {
431+
return projectRouting;
432+
}
433+
434+
public void projectRouting(String projectRouting) {
435+
this.projectRouting = projectRouting;
436+
}
437+
426438
public AbstractSqlQueryRequest(StreamInput in) throws IOException {
427439
super(in);
428440
query = in.readString();

x-pack/plugin/sql/sql-action/src/main/java/org/elasticsearch/xpack/sql/action/SqlTranslateRequestBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,9 @@ public SqlTranslateRequestBuilder zoneId(ZoneId zoneId) {
6868
request.zoneId(zoneId);
6969
return this;
7070
}
71+
72+
public SqlTranslateRequestBuilder projectRouting(String projectRouting) {
73+
request.projectRouting(projectRouting);
74+
return this;
75+
}
7176
}

x-pack/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/proto/CoreProtocol.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class CoreProtocol {
3636
public static final String INDEX_INCLUDE_FROZEN_NAME = "index_include_frozen";
3737
public static final String RUNTIME_MAPPINGS_NAME = "runtime_mappings";
3838
public static final String ALLOW_PARTIAL_SEARCH_RESULTS_NAME = "allow_partial_search_results";
39+
public static final String PROJECT_ROUTING_NAME = "project_routing";
3940
// async
4041
public static final String WAIT_FOR_COMPLETION_TIMEOUT_NAME = "wait_for_completion_timeout";
4142
public static final String KEEP_ON_COMPLETION_NAME = "keep_on_completion";

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/RestSqlQueryAction.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
import org.elasticsearch.rest.Scope;
1717
import org.elasticsearch.rest.ServerlessScope;
1818
import org.elasticsearch.rest.action.RestCancellableNodeClient;
19+
import org.elasticsearch.search.crossproject.CrossProjectModeDecider;
1920
import org.elasticsearch.xcontent.XContentParser;
21+
import org.elasticsearch.xpack.ql.InvalidArgumentException;
2022
import org.elasticsearch.xpack.sql.action.SqlQueryAction;
2123
import org.elasticsearch.xpack.sql.action.SqlQueryRequest;
2224

@@ -34,10 +36,11 @@
3436
@ServerlessScope(Scope.PUBLIC)
3537
public class RestSqlQueryAction extends BaseRestHandler {
3638
private static final Logger LOGGER = LogManager.getLogger(RestSqlQueryAction.class);
37-
private final Settings settings;
39+
40+
private final CrossProjectModeDecider crossProjectModeDecider;
3841

3942
public RestSqlQueryAction(Settings settings) {
40-
this.settings = settings;
43+
crossProjectModeDecider = new CrossProjectModeDecider(settings);
4144
}
4245

4346
@Override
@@ -47,15 +50,21 @@ public List<Route> routes() {
4750

4851
@Override
4952
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
50-
if (settings != null && settings.getAsBoolean("serverless.cross_project.enabled", false)) {
51-
// accept but drop project_routing param until fully supported
52-
request.param("project_routing");
53-
}
53+
5454
SqlQueryRequest sqlRequest;
5555
try (XContentParser parser = request.contentOrSourceParamParser()) {
5656
sqlRequest = SqlQueryRequest.fromXContent(parser);
5757
}
5858

59+
String routingParam = request.param("project_routing");
60+
if (routingParam != null) {
61+
// takes precedence on the parameter in the body
62+
sqlRequest.projectRouting(routingParam);
63+
}
64+
if (sqlRequest.projectRouting() != null && crossProjectModeDecider.crossProjectEnabled() == false) {
65+
throw new InvalidArgumentException("[project_routing] is only allowed when cross-project search is enabled");
66+
}
67+
5968
return channel -> {
6069
RestCancellableNodeClient cancellableClient = new RestCancellableNodeClient(client, request.getHttpChannel());
6170
cancellableClient.execute(

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/RestSqlTranslateAction.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77
package org.elasticsearch.xpack.sql.plugin;
88

99
import org.elasticsearch.client.internal.node.NodeClient;
10+
import org.elasticsearch.common.settings.Settings;
1011
import org.elasticsearch.rest.BaseRestHandler;
1112
import org.elasticsearch.rest.RestRequest;
1213
import org.elasticsearch.rest.Scope;
1314
import org.elasticsearch.rest.ServerlessScope;
1415
import org.elasticsearch.rest.action.RestToXContentListener;
16+
import org.elasticsearch.search.crossproject.CrossProjectModeDecider;
1517
import org.elasticsearch.xcontent.XContentParser;
18+
import org.elasticsearch.xpack.ql.InvalidArgumentException;
1619
import org.elasticsearch.xpack.sql.action.SqlTranslateAction;
1720
import org.elasticsearch.xpack.sql.action.SqlTranslateRequest;
1821

@@ -29,6 +32,12 @@
2932
@ServerlessScope(Scope.PUBLIC)
3033
public class RestSqlTranslateAction extends BaseRestHandler {
3134

35+
private final CrossProjectModeDecider crossProjectModeDecider;
36+
37+
public RestSqlTranslateAction(Settings settings) {
38+
this.crossProjectModeDecider = new CrossProjectModeDecider(settings);
39+
}
40+
3241
@Override
3342
public List<Route> routes() {
3443
return List.of(new Route(GET, SQL_TRANSLATE_REST_ENDPOINT), new Route(POST, SQL_TRANSLATE_REST_ENDPOINT));
@@ -40,7 +49,14 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
4049
try (XContentParser parser = request.contentOrSourceParamParser()) {
4150
sqlRequest = SqlTranslateRequest.fromXContent(parser);
4251
}
43-
52+
String routingParam = request.param("project_routing");
53+
if (routingParam != null) {
54+
// takes precedence on the parameter in the body
55+
sqlRequest.projectRouting(routingParam);
56+
}
57+
if (sqlRequest.projectRouting() != null && crossProjectModeDecider.crossProjectEnabled() == false) {
58+
throw new InvalidArgumentException("[project_routing] is only allowed when cross-project search is enabled");
59+
}
4460
return channel -> client.executeLocally(SqlTranslateAction.INSTANCE, sqlRequest, new RestToXContentListener<>(channel));
4561
}
4662

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public List<RestHandler> getRestHandlers(
123123

124124
return Arrays.asList(
125125
new RestSqlQueryAction(settings),
126-
new RestSqlTranslateAction(),
126+
new RestSqlTranslateAction(settings),
127127
new RestSqlClearCursorAction(),
128128
new RestSqlStatsAction(),
129129
new RestSqlAsyncGetResultsAction(),

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/TransportSqlQueryAction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ public static void operation(
155155
request.indexIncludeFrozen(),
156156
new TaskId(clusterService.localNode().getId(), task.getId()),
157157
task,
158-
request.allowPartialSearchResults()
158+
request.allowPartialSearchResults(),
159+
request.projectRouting()
159160
);
160161

161162
if (Strings.hasText(request.cursor()) == false) {

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/TransportSqlTranslateAction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ protected void doExecute(Task task, SqlTranslateRequest request, ActionListener<
7878
Protocol.INDEX_INCLUDE_FROZEN,
7979
null,
8080
null,
81-
Protocol.ALLOW_PARTIAL_SEARCH_RESULTS
81+
Protocol.ALLOW_PARTIAL_SEARCH_RESULTS,
82+
request.projectRouting()
8283
);
8384

8485
planExecutor.searchSource(

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/session/SqlConfiguration.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class SqlConfiguration extends org.elasticsearch.xpack.ql.session.Configu
4343
@Nullable
4444
private final Map<String, Object> runtimeMappings;
4545
private final boolean allowPartialSearchResults;
46+
private final String projectRouting;
4647

4748
public SqlConfiguration(
4849
ZoneId zi,
@@ -61,7 +62,8 @@ public SqlConfiguration(
6162
boolean includeFrozen,
6263
@Nullable TaskId taskId,
6364
@Nullable SqlQueryTask task,
64-
boolean allowPartialSearchResults
65+
boolean allowPartialSearchResults,
66+
String projectRouting
6567
) {
6668
super(zi, username, clusterName);
6769

@@ -79,6 +81,7 @@ public SqlConfiguration(
7981
this.taskId = taskId;
8082
this.task = task;
8183
this.allowPartialSearchResults = allowPartialSearchResults;
84+
this.projectRouting = projectRouting;
8285
}
8386

8487
public String catalog() {
@@ -136,4 +139,8 @@ public SqlQueryTask task() {
136139
public boolean allowPartialSearchResults() {
137140
return allowPartialSearchResults;
138141
}
142+
143+
public String projectRouting() {
144+
return projectRouting;
145+
}
139146
}

0 commit comments

Comments
 (0)