Skip to content

Commit 06bfcfa

Browse files
committed
upd
1 parent ee777a4 commit 06bfcfa

File tree

7 files changed

+49
-98
lines changed

7 files changed

+49
-98
lines changed

server/src/main/java/org/elasticsearch/indices/IndicesExpressionGrouper.java

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@
1111

1212
import org.elasticsearch.action.OriginalIndices;
1313
import org.elasticsearch.action.support.IndicesOptions;
14-
import org.elasticsearch.common.Strings;
1514

1615
import java.util.Map;
17-
import java.util.Set;
1816

1917
/**
2018
* Interface for grouping index expressions, along with IndicesOptions by cluster alias.
@@ -30,36 +28,7 @@
3028
public interface IndicesExpressionGrouper {
3129

3230
/**
33-
* @param remoteClusterNames Set of configured remote cluster names.
34-
* @param indicesOptions IndicesOptions to clarify how the index expression should be parsed/applied
35-
* @param indexExpressionCsv Multiple index expressions as CSV string (with no spaces), e.g., "logs1,logs2,cluster-a:logs1".
36-
* A single index expression is also supported.
37-
* @return Map where the key is the cluster alias (for "local" cluster, it is RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY)
38-
* and the value for that cluster from the index expression is an OriginalIndices object.
31+
* See {@link org.elasticsearch.transport.RemoteClusterService#groupIndices} for details
3932
*/
40-
default Map<String, OriginalIndices> groupIndices(
41-
Set<String> remoteClusterNames,
42-
IndicesOptions indicesOptions,
43-
String indexExpressionCsv
44-
) {
45-
return groupIndices(remoteClusterNames, indicesOptions, Strings.splitStringByCommaToArray(indexExpressionCsv));
46-
}
47-
48-
/**
49-
* Same behavior as the other groupIndices, except the incoming multiple index expressions must already be
50-
* parsed into a String array.
51-
* @param remoteClusterNames Set of configured remote cluster names.
52-
* @param indicesOptions IndicesOptions to clarify how the index expressions should be parsed/applied
53-
* @param indexExpressions Multiple index expressions as string[].
54-
* @return Map where the key is the cluster alias (for "local" cluster, it is RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY)
55-
* and the value for that cluster from the index expression is an OriginalIndices object.
56-
*/
57-
Map<String, OriginalIndices> groupIndices(Set<String> remoteClusterNames, IndicesOptions indicesOptions, String[] indexExpressions);
58-
59-
/**
60-
* Returns a set of currently configured remote clusters.
61-
*/
62-
default Set<String> getConfiguredClusters() {
63-
return Set.of();
64-
}
33+
Map<String, OriginalIndices> groupIndices(IndicesOptions indicesOptions, String[] indexExpressions, boolean returnLocalAll);
6534
}

server/src/main/java/org/elasticsearch/transport/RemoteClusterService.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ public Map<String, OriginalIndices> groupIndices(Set<String> remoteClusterNames,
168168
return groupIndices(remoteClusterNames, indicesOptions, indices, true);
169169
}
170170

171+
@Override
171172
public Map<String, OriginalIndices> groupIndices(IndicesOptions indicesOptions, String[] indices, boolean returnLocalAll) {
172173
return groupIndices(getRegisteredRemoteClusterNames(), indicesOptions, indices, returnLocalAll);
173174
}
@@ -176,11 +177,6 @@ public Map<String, OriginalIndices> groupIndices(IndicesOptions indicesOptions,
176177
return groupIndices(getRegisteredRemoteClusterNames(), indicesOptions, indices, true);
177178
}
178179

179-
@Override
180-
public Set<String> getConfiguredClusters() {
181-
return getRegisteredRemoteClusterNames();
182-
}
183-
184180
/**
185181
* Returns the registered remote cluster names.
186182
*/

x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterQueriesWithInvalidLicenseIT.java

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import org.elasticsearch.ElasticsearchStatusException;
1111
import org.elasticsearch.core.Tuple;
1212
import org.elasticsearch.plugins.Plugin;
13-
import org.elasticsearch.xpack.esql.VerificationException;
1413
import org.elasticsearch.xpack.esql.plan.logical.Enrich;
1514

1615
import java.util.ArrayList;
@@ -66,30 +65,20 @@ public void testQueryAgainstNonMatchingClusterWildcardPattern() {
6665

6766
// since this wildcarded expression does not resolve to a valid remote cluster, it is not considered
6867
// a cross-cluster search and thus should not throw a license error
69-
expectThrows(
70-
VerificationException.class,
71-
containsString("Unknown index [xremote*:events]"),
72-
() -> runQuery("FROM xremote*:events | STATS count(*)", requestIncludeMeta).close()
73-
);
74-
// try (EsqlQueryResponse resp = runQuery("FROM xremote*:events | STATS count(*)", requestIncludeMeta)) {
75-
// assertThat(resp.columns().size(), equalTo(1));
76-
// EsqlExecutionInfo executionInfo = resp.getExecutionInfo();
77-
// assertThat(executionInfo.isCrossClusterSearch(), is(false));
78-
// assertThat(executionInfo.includeCCSMetadata(), equalTo(responseExpectMeta));
79-
// }
80-
81-
expectThrows(
82-
VerificationException.class,
83-
containsString("Unknown index [xremote*:events]"),
84-
() -> runQuery("FROM xremote*:events | STATS count(*)", requestIncludeMeta).close()
85-
);
86-
// try (EsqlQueryResponse resp = runQuery("FROM xremote*:events | LIMIT 0", requestIncludeMeta)) {
87-
// assertThat(resp.columns().size(), equalTo(1));
88-
// assertThat(getValuesList(resp).size(), equalTo(0));
89-
// EsqlExecutionInfo executionInfo = resp.getExecutionInfo();
90-
// assertThat(executionInfo.isCrossClusterSearch(), is(false));
91-
// assertThat(executionInfo.includeCCSMetadata(), equalTo(responseExpectMeta));
92-
// }
68+
try (EsqlQueryResponse resp = runQuery("FROM xremote*:events | STATS count(*)", requestIncludeMeta)) {
69+
assertThat(resp.columns().size(), equalTo(1));
70+
EsqlExecutionInfo executionInfo = resp.getExecutionInfo();
71+
assertThat(executionInfo.isCrossClusterSearch(), is(false));
72+
assertThat(executionInfo.includeCCSMetadata(), equalTo(responseExpectMeta));
73+
}
74+
75+
try (EsqlQueryResponse resp = runQuery("FROM xremote*:events | LIMIT 0", requestIncludeMeta)) {
76+
assertThat(resp.columns().size(), equalTo(1));
77+
assertThat(getValuesList(resp).size(), equalTo(0));
78+
EsqlExecutionInfo executionInfo = resp.getExecutionInfo();
79+
assertThat(executionInfo.isCrossClusterSearch(), is(false));
80+
assertThat(executionInfo.includeCCSMetadata(), equalTo(responseExpectMeta));
81+
}
9382
}
9483

9584
public void testCCSWithLimit0() {

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlCCSUtils.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.elasticsearch.transport.ConnectTransportException;
2424
import org.elasticsearch.transport.NoSuchRemoteClusterException;
2525
import org.elasticsearch.transport.RemoteClusterAware;
26-
import org.elasticsearch.transport.RemoteClusterService;
2726
import org.elasticsearch.transport.RemoteTransportException;
2827
import org.elasticsearch.xpack.esql.VerificationException;
2928
import org.elasticsearch.xpack.esql.action.EsqlExecutionInfo;
@@ -316,11 +315,9 @@ public static void initCrossClusterState(
316315
}
317316
try {
318317
var groupedIndices = indicesGrouper.groupIndices(
319-
// indicesGrouper.getConfiguredClusters() might return mutable set that changes as clusters connect or disconnect.
320-
// it is copied here so that we have the same resolution when request contains multiple remote cluster patterns with *
321-
Set.copyOf(indicesGrouper.getConfiguredClusters()),
322318
IndicesOptions.DEFAULT,
323-
indexPattern.indexPattern()
319+
Strings.splitStringByCommaToArray(indexPattern.indexPattern()),
320+
false
324321
);
325322

326323
executionInfo.clusterInfoInitializing(true);
@@ -339,11 +336,8 @@ public static void initCrossClusterState(
339336
executionInfo.clusterInfoInitializing(false);
340337
}
341338

342-
// check if it is a cross-cluster query
343-
if (groupedIndices.size() > 1 || groupedIndices.containsKey(RemoteClusterService.LOCAL_CLUSTER_GROUP_KEY) == false) {
344-
if (EsqlLicenseChecker.isCcsAllowed(licenseState) == false) {
345-
throw EsqlLicenseChecker.invalidLicenseForCcsException(licenseState);
346-
}
339+
if (executionInfo.isCrossClusterSearch() && EsqlLicenseChecker.isCcsAllowed(licenseState) == false) {
340+
throw EsqlLicenseChecker.invalidLicenseForCcsException(licenseState);
347341
}
348342
} catch (NoSuchRemoteClusterException e) {
349343
if (EsqlLicenseChecker.isCcsAllowed(licenseState)) {

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -647,25 +647,32 @@ private void preAnalyzeMainIndices(
647647
ThreadPool.Names.SYSTEM_READ
648648
);
649649
if (preAnalysis.indexPattern() != null) {
650-
indexResolver.resolveAsMergedMapping(
651-
preAnalysis.indexPattern().indexPattern(),
652-
result.fieldNames,
653-
// Maybe if no indices are returned, retry without index mode and provide a clearer error message.
654-
switch (preAnalysis.indexMode()) {
655-
case IndexMode.TIME_SERIES -> {
656-
var indexModeFilter = new TermQueryBuilder(IndexModeFieldMapper.NAME, IndexMode.TIME_SERIES.getName());
657-
yield requestFilter != null
658-
? new BoolQueryBuilder().filter(requestFilter).filter(indexModeFilter)
659-
: indexModeFilter;
660-
}
661-
default -> requestFilter;
662-
},
663-
preAnalysis.indexMode() == IndexMode.TIME_SERIES,
664-
listener.delegateFailureAndWrap((l, indexResolution) -> {
665-
EsqlCCSUtils.updateExecutionInfoWithUnavailableClusters(executionInfo, indexResolution.failures());
666-
l.onResponse(result.withIndices(indexResolution));
667-
})
668-
);
650+
if (executionInfo.clusterAliases().isEmpty()) {
651+
// if this was a pure remote CCS request (no local indices) and all remotes are offline, return an empty IndexResolution
652+
listener.onResponse(
653+
result.withIndices(IndexResolution.valid(new EsIndex(preAnalysis.indexPattern().indexPattern(), Map.of(), Map.of())))
654+
);
655+
} else {
656+
indexResolver.resolveAsMergedMapping(
657+
preAnalysis.indexPattern().indexPattern(),
658+
result.fieldNames,
659+
// Maybe if no indices are returned, retry without index mode and provide a clearer error message.
660+
switch (preAnalysis.indexMode()) {
661+
case IndexMode.TIME_SERIES -> {
662+
var indexModeFilter = new TermQueryBuilder(IndexModeFieldMapper.NAME, IndexMode.TIME_SERIES.getName());
663+
yield requestFilter != null
664+
? new BoolQueryBuilder().filter(requestFilter).filter(indexModeFilter)
665+
: indexModeFilter;
666+
}
667+
default -> requestFilter;
668+
},
669+
preAnalysis.indexMode() == IndexMode.TIME_SERIES,
670+
listener.delegateFailureAndWrap((l, indexResolution) -> {
671+
EsqlCCSUtils.updateExecutionInfoWithUnavailableClusters(executionInfo, indexResolution.failures());
672+
l.onResponse(result.withIndices(indexResolution));
673+
})
674+
);
675+
}
669676
} else {
670677
// occurs when dealing with local relations (row a = 1)
671678
listener.onResponse(result.withIndices(IndexResolution.invalid("[none specified]")));

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/EsqlCCSUtilsTests.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -743,11 +743,7 @@ private XPackLicenseStatus inactiveLicenseStatus(License.OperationMode operation
743743

744744
static class TestIndicesExpressionGrouper implements IndicesExpressionGrouper {
745745
@Override
746-
public Map<String, OriginalIndices> groupIndices(
747-
Set<String> remoteClusterNames,
748-
IndicesOptions indicesOptions,
749-
String[] indexExpressions
750-
) {
746+
public Map<String, OriginalIndices> groupIndices(IndicesOptions indicesOptions, String[] indexExpressions, boolean returnLocalAll) {
751747
final Map<String, OriginalIndices> originalIndicesMap = new HashMap<>();
752748
final String localKey = RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY;
753749

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/PlanExecutorMetricsTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public void testFailedMetric() {
157157
// test a failed query: xyz field doesn't exist
158158
request.query("from test | stats m = max(xyz)");
159159
EsqlSession.PlanRunner runPhase = (p, r) -> fail("this shouldn't happen");
160-
IndicesExpressionGrouper groupIndicesByCluster = (remoteClusterNames, indicesOptions, indexExpressions) -> Map.of(
160+
IndicesExpressionGrouper groupIndicesByCluster = (indicesOptions, indexExpressions, returnLocalAll) -> Map.of(
161161
"",
162162
new OriginalIndices(new String[] { "test" }, IndicesOptions.DEFAULT)
163163
);

0 commit comments

Comments
 (0)