Skip to content

Commit d185356

Browse files
committed
look for unavailable shards exceptions
1 parent 56fb6ce commit d185356

File tree

6 files changed

+36
-30
lines changed

6 files changed

+36
-30
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ protected final EsqlQueryResponse run(String esqlCommands, QueryPragmas pragmas)
166166
}
167167

168168
protected EsqlQueryResponse run(String esqlCommands, QueryPragmas pragmas, QueryBuilder filter) {
169+
return run(esqlCommands, pragmas, filter, null);
170+
}
171+
172+
protected EsqlQueryResponse run(String esqlCommands, QueryPragmas pragmas, QueryBuilder filter, Boolean allowPartialResults) {
169173
EsqlQueryRequest request = EsqlQueryRequest.syncEsqlQueryRequest();
170174
request.query(esqlCommands);
171175
if (pragmas != null) {
@@ -174,6 +178,9 @@ protected EsqlQueryResponse run(String esqlCommands, QueryPragmas pragmas, Query
174178
if (filter != null) {
175179
request.filter(filter);
176180
}
181+
if (allowPartialResults != null) {
182+
request.allowPartialResults(allowPartialResults);
183+
}
177184
return run(request);
178185
}
179186

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ public void testFailOnUnavailableShards() throws Exception {
265265
containsString("index [logs] has no active shard copy"),
266266
() -> run("from * | KEEP timestamp,message")
267267
);
268+
try (EsqlQueryResponse resp = run("from events,logs | KEEP timestamp,message", null, null, true)) {
269+
assertThat(getValuesList(resp), hasSize(3));
270+
}
268271
}
269272

270273
public void testSkipOnIndexName() {

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/index/IndexResolution.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
package org.elasticsearch.xpack.esql.index;
88

9+
import org.elasticsearch.action.NoShardAvailableActionException;
910
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesFailure;
1011
import org.elasticsearch.core.Nullable;
1112

@@ -18,32 +19,33 @@ public final class IndexResolution {
1819
/**
1920
* @param index EsIndex encapsulating requested index expression, resolved mappings and index modes from field-caps.
2021
* @param resolvedIndices Set of concrete indices resolved by field-caps. (This information is not always present in the EsIndex).
22+
* @param unavailableShards Set of shards that were unavailable during index resolution
2123
* @param unavailableClusters Remote clusters that could not be contacted during planning
2224
* @return valid IndexResolution
2325
*/
2426
public static IndexResolution valid(
2527
EsIndex index,
2628
Set<String> resolvedIndices,
27-
FieldCapabilitiesFailure localResolutionFailure,
29+
Set<NoShardAvailableActionException> unavailableShards,
2830
Map<String, FieldCapabilitiesFailure> unavailableClusters
2931
) {
3032
Objects.requireNonNull(index, "index must not be null if it was found");
3133
Objects.requireNonNull(resolvedIndices, "resolvedIndices must not be null");
32-
Objects.requireNonNull(resolvedIndices, "resolutionFailures must not be null");
34+
Objects.requireNonNull(unavailableShards, "unavailableShards must not be null");
3335
Objects.requireNonNull(unavailableClusters, "unavailableClusters must not be null");
34-
return new IndexResolution(index, null, resolvedIndices, localResolutionFailure, unavailableClusters);
36+
return new IndexResolution(index, null, resolvedIndices, unavailableShards, unavailableClusters);
3537
}
3638

3739
/**
3840
* Use this method only if the set of concrete resolved indices is the same as EsIndex#concreteIndices().
3941
*/
4042
public static IndexResolution valid(EsIndex index) {
41-
return valid(index, index.concreteIndices(), null, Map.of());
43+
return valid(index, index.concreteIndices(), Set.of(), Map.of());
4244
}
4345

4446
public static IndexResolution invalid(String invalid) {
4547
Objects.requireNonNull(invalid, "invalid must not be null to signal that the index is invalid");
46-
return new IndexResolution(null, invalid, Set.of(), null, Map.of());
48+
return new IndexResolution(null, invalid, Set.of(), Set.of(), Map.of());
4749
}
4850

4951
public static IndexResolution notFound(String name) {
@@ -57,22 +59,21 @@ public static IndexResolution notFound(String name) {
5759

5860
// all indices found by field-caps
5961
private final Set<String> resolvedIndices;
60-
@Nullable
61-
private final FieldCapabilitiesFailure localResolutionFailure;
62+
private final Set<NoShardAvailableActionException> unavailableShards;
6263
// remote clusters included in the user's index expression that could not be connected to
6364
private final Map<String, FieldCapabilitiesFailure> unavailableClusters;
6465

6566
private IndexResolution(
6667
EsIndex index,
6768
@Nullable String invalid,
6869
Set<String> resolvedIndices,
69-
@Nullable FieldCapabilitiesFailure localResolutionFailure,
70+
Set<NoShardAvailableActionException> unavailableShards,
7071
Map<String, FieldCapabilitiesFailure> unavailableClusters
7172
) {
7273
this.index = index;
7374
this.invalid = invalid;
7475
this.resolvedIndices = resolvedIndices;
75-
this.localResolutionFailure = localResolutionFailure;
76+
this.unavailableShards = unavailableShards;
7677
this.unavailableClusters = unavailableClusters;
7778
}
7879

@@ -115,11 +116,10 @@ public Set<String> resolvedIndices() {
115116
}
116117

117118
/**
118-
* @return local cluster index resolution failure if present
119+
* @return set of unavailable shards during index resolution
119120
*/
120-
@Nullable
121-
public FieldCapabilitiesFailure getLocalResolutionFailure() {
122-
return localResolutionFailure;
121+
public Set<NoShardAvailableActionException> getUnavailableShards() {
122+
return unavailableShards;
123123
}
124124

125125
@Override

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,8 +483,8 @@ private void preAnalyzeIndices(
483483
result.fieldNames,
484484
requestFilter,
485485
listener.delegateFailure((l, indexResolution) -> {
486-
if (configuration.allowPartialResults() == false && indexResolution.getLocalResolutionFailure() != null) {
487-
l.onFailure(indexResolution.getLocalResolutionFailure().getException());
486+
if (configuration.allowPartialResults() == false && indexResolution.getUnavailableShards().isEmpty() == false) {
487+
l.onFailure(indexResolution.getUnavailableShards().iterator().next());
488488
} else {
489489
l.onResponse(result.withIndexResolution(indexResolution));
490490
}

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

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
*/
77
package org.elasticsearch.xpack.esql.session;
88

9-
import org.elasticsearch.ExceptionsHelper;
109
import org.elasticsearch.action.ActionListener;
10+
import org.elasticsearch.action.NoShardAvailableActionException;
1111
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesFailure;
1212
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesIndexResponse;
1313
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest;
@@ -88,10 +88,7 @@ public void resolveAsMergedMapping(
8888
client.execute(
8989
EsqlResolveFieldsAction.TYPE,
9090
createFieldCapsRequest(indexWildcard, fieldNames, requestFilter),
91-
listener.delegateFailureAndWrap((l, response) -> {
92-
93-
l.onResponse(mergedMappings(indexWildcard, response));
94-
})
91+
listener.delegateFailureAndWrap((l, response) -> l.onResponse(mergedMappings(indexWildcard, response)))
9592
);
9693
}
9794

@@ -156,11 +153,10 @@ public static IndexResolution mergedMappings(String indexPattern, FieldCapabilit
156153
fieldCapsResponse.getFailures()
157154
);
158155

159-
FieldCapabilitiesFailure localResolutionFailure = null;
156+
Set<NoShardAvailableActionException> unavailableShards = new HashSet<>();
160157
for (FieldCapabilitiesFailure failure : fieldCapsResponse.getFailures()) {
161-
if (ExceptionsHelper.isRemoteUnavailableException(failure.getException()) == false) {
162-
localResolutionFailure = failure;
163-
break;
158+
if (failure.getException() instanceof NoShardAvailableActionException e) {
159+
unavailableShards.add(e);
164160
}
165161
}
166162

@@ -175,7 +171,7 @@ public static IndexResolution mergedMappings(String indexPattern, FieldCapabilit
175171
}
176172
// If all the mappings are empty we return an empty set of resolved indices to line up with QL
177173
var index = new EsIndex(indexPattern, rootFields, allEmpty ? Map.of() : concreteIndices, partiallyUnmappedFields);
178-
return IndexResolution.valid(index, concreteIndices.keySet(), localResolutionFailure, unavailableRemotes);
174+
return IndexResolution.valid(index, concreteIndices.keySet(), unavailableShards, unavailableRemotes);
179175
}
180176

181177
private static Map<String, List<IndexFieldCapabilities>> collectFieldCaps(FieldCapabilitiesResponse fieldCapsResponse) {

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ public void testUpdateExecutionInfoWithClustersWithNoMatchingIndices() {
254254
)
255255
);
256256

257-
IndexResolution indexResolution = IndexResolution.valid(esIndex, esIndex.concreteIndices(), null, Map.of());
257+
IndexResolution indexResolution = IndexResolution.valid(esIndex, esIndex.concreteIndices(), Set.of(), Map.of());
258258

259259
EsqlCCSUtils.updateExecutionInfoWithClustersWithNoMatchingIndices(executionInfo, indexResolution);
260260

@@ -298,7 +298,7 @@ public void testUpdateExecutionInfoWithClustersWithNoMatchingIndices() {
298298
)
299299
);
300300
Map<String, FieldCapabilitiesFailure> unavailableClusters = Map.of();
301-
IndexResolution indexResolution = IndexResolution.valid(esIndex, esIndex.concreteIndices(), null, unavailableClusters);
301+
IndexResolution indexResolution = IndexResolution.valid(esIndex, esIndex.concreteIndices(), Set.of(), unavailableClusters);
302302

303303
EsqlCCSUtils.updateExecutionInfoWithClustersWithNoMatchingIndices(executionInfo, indexResolution);
304304

@@ -340,7 +340,7 @@ public void testUpdateExecutionInfoWithClustersWithNoMatchingIndices() {
340340
// remote1 is unavailable
341341
var failure = new FieldCapabilitiesFailure(new String[] { "logs-a" }, new NoSeedNodeLeftException("unable to connect"));
342342
Map<String, FieldCapabilitiesFailure> unavailableClusters = Map.of(REMOTE1_ALIAS, failure);
343-
IndexResolution indexResolution = IndexResolution.valid(esIndex, esIndex.concreteIndices(), null, unavailableClusters);
343+
IndexResolution indexResolution = IndexResolution.valid(esIndex, esIndex.concreteIndices(), Set.of(), unavailableClusters);
344344

345345
EsqlCCSUtils.updateExecutionInfoWithClustersWithNoMatchingIndices(executionInfo, indexResolution);
346346

@@ -383,7 +383,7 @@ public void testUpdateExecutionInfoWithClustersWithNoMatchingIndices() {
383383

384384
var failure = new FieldCapabilitiesFailure(new String[] { "logs-a" }, new NoSeedNodeLeftException("unable to connect"));
385385
Map<String, FieldCapabilitiesFailure> unavailableClusters = Map.of(REMOTE1_ALIAS, failure);
386-
IndexResolution indexResolution = IndexResolution.valid(esIndex, esIndex.concreteIndices(), null, unavailableClusters);
386+
IndexResolution indexResolution = IndexResolution.valid(esIndex, esIndex.concreteIndices(), Set.of(), unavailableClusters);
387387
VerificationException ve = expectThrows(
388388
VerificationException.class,
389389
() -> EsqlCCSUtils.updateExecutionInfoWithClustersWithNoMatchingIndices(executionInfo, indexResolution)
@@ -417,7 +417,7 @@ public void testUpdateExecutionInfoWithClustersWithNoMatchingIndices() {
417417
// remote1 is unavailable
418418
var failure = new FieldCapabilitiesFailure(new String[] { "logs-a" }, new NoSeedNodeLeftException("unable to connect"));
419419
Map<String, FieldCapabilitiesFailure> unavailableClusters = Map.of(REMOTE1_ALIAS, failure);
420-
IndexResolution indexResolution = IndexResolution.valid(esIndex, esIndex.concreteIndices(), null, unavailableClusters);
420+
IndexResolution indexResolution = IndexResolution.valid(esIndex, esIndex.concreteIndices(), Set.of(), unavailableClusters);
421421

422422
EsqlCCSUtils.updateExecutionInfoWithClustersWithNoMatchingIndices(executionInfo, indexResolution);
423423

0 commit comments

Comments
 (0)