Skip to content

Commit 53606ba

Browse files
committed
Relax error handling in transport disk usage API (#84774)
Relax the failure handling to cover other exceptions such as BroadcastShardOperationFailedException.
1 parent fbe7cf7 commit 53606ba

File tree

3 files changed

+97
-2
lines changed

3 files changed

+97
-2
lines changed

docs/changelog/84774.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 84774
2+
summary: Increase store ref before analyzing disk usage
3+
area: Search
4+
type: bug
5+
issues: []

server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/diskusage/IndexDiskUsageAnalyzerIT.java

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,65 @@
1313
import org.elasticsearch.action.support.PlainActionFuture;
1414
import org.elasticsearch.cluster.metadata.IndexMetadata;
1515
import org.elasticsearch.common.settings.Settings;
16+
import org.elasticsearch.common.util.CollectionUtils;
17+
import org.elasticsearch.common.util.set.Sets;
18+
import org.elasticsearch.index.Index;
19+
import org.elasticsearch.index.IndexSettings;
20+
import org.elasticsearch.index.engine.EngineException;
21+
import org.elasticsearch.index.engine.EngineFactory;
22+
import org.elasticsearch.index.engine.InternalEngine;
23+
import org.elasticsearch.index.shard.ShardId;
24+
import org.elasticsearch.plugins.EnginePlugin;
25+
import org.elasticsearch.plugins.Plugin;
1626
import org.elasticsearch.test.ESIntegTestCase;
1727
import org.elasticsearch.xcontent.XContentBuilder;
1828
import org.elasticsearch.xcontent.XContentFactory;
29+
import org.junit.Before;
30+
31+
import java.util.Collection;
32+
import java.util.List;
33+
import java.util.Optional;
34+
import java.util.Set;
35+
import java.util.stream.IntStream;
1936

2037
import static org.hamcrest.Matchers.equalTo;
2138
import static org.hamcrest.Matchers.greaterThan;
2239

2340
public class IndexDiskUsageAnalyzerIT extends ESIntegTestCase {
2441

42+
@Override
43+
protected boolean addMockInternalEngine() {
44+
return false;
45+
}
46+
47+
@Override
48+
protected Collection<Class<? extends Plugin>> nodePlugins() {
49+
return CollectionUtils.appendToCopy(super.nodePlugins(), EngineTestPlugin.class);
50+
}
51+
52+
private static final Set<ShardId> failOnFlushShards = Sets.newConcurrentHashSet();
53+
54+
public static class EngineTestPlugin extends Plugin implements EnginePlugin {
55+
@Override
56+
public Optional<EngineFactory> getEngineFactory(IndexSettings indexSettings) {
57+
return Optional.of(config -> new InternalEngine(config) {
58+
@Override
59+
public void flush(boolean force, boolean waitIfOngoing) throws EngineException {
60+
final ShardId shardId = config.getShardId();
61+
if (failOnFlushShards.contains(shardId)) {
62+
throw new EngineException(shardId, "simulated IO");
63+
}
64+
super.flush(force, waitIfOngoing);
65+
}
66+
});
67+
}
68+
}
69+
70+
@Before
71+
public void resetFailOnFlush() throws Exception {
72+
failOnFlushShards.clear();
73+
}
74+
2575
public void testSimple() throws Exception {
2676
final XContentBuilder mapping = XContentFactory.jsonBuilder();
2777
mapping.startObject();
@@ -152,6 +202,43 @@ public void testGeoShape() throws Exception {
152202
assertMetadataFields(stats);
153203
}
154204

205+
public void testFailOnFlush() throws Exception {
206+
final String indexName = "test-index";
207+
int numberOfShards = between(1, 5);
208+
client().admin()
209+
.indices()
210+
.prepareCreate(indexName)
211+
.setSettings(
212+
Settings.builder()
213+
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, numberOfShards)
214+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, between(0, 1))
215+
)
216+
.get();
217+
ensureYellow(indexName);
218+
int numDocs = randomIntBetween(1, 10);
219+
for (int i = 0; i < numDocs; i++) {
220+
int value = randomIntBetween(1, 10);
221+
final XContentBuilder doc = XContentFactory.jsonBuilder()
222+
.startObject()
223+
.field("english_text", English.intToEnglish(value))
224+
.field("value", value)
225+
.endObject();
226+
client().prepareIndex(indexName).setId("id-" + i).setSource(doc).get();
227+
}
228+
Index index = clusterService().state().metadata().index(indexName).getIndex();
229+
List<ShardId> failedShards = randomSubsetOf(
230+
between(1, numberOfShards),
231+
IntStream.range(0, numberOfShards).mapToObj(n -> new ShardId(index, n)).toList()
232+
);
233+
failOnFlushShards.addAll(failedShards);
234+
AnalyzeIndexDiskUsageResponse resp = client().execute(
235+
AnalyzeIndexDiskUsageAction.INSTANCE,
236+
new AnalyzeIndexDiskUsageRequest(new String[] { indexName }, AnalyzeIndexDiskUsageRequest.DEFAULT_INDICES_OPTIONS, true)
237+
).actionGet();
238+
assertThat(resp.getTotalShards(), equalTo(numberOfShards));
239+
assertThat(resp.getFailedShards(), equalTo(failedShards.size()));
240+
}
241+
155242
void assertMetadataFields(IndexDiskUsageStats stats) {
156243
final IndexDiskUsageStats.PerFieldDiskUsage sourceField = stats.getFields().get("_source");
157244
assertThat(sourceField.getInvertedIndexBytes(), equalTo(0L));

server/src/main/java/org/elasticsearch/action/admin/indices/diskusage/TransportAnalyzeIndexDiskUsageAction.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
package org.elasticsearch.action.admin.indices.diskusage;
1010

11+
import org.elasticsearch.ExceptionsHelper;
1112
import org.elasticsearch.action.ActionListener;
1213
import org.elasticsearch.action.NoShardAvailableActionException;
1314
import org.elasticsearch.action.support.ActionFilters;
@@ -109,8 +110,10 @@ protected AnalyzeIndexDiskUsageResponse newResponse(
109110
if (r instanceof AnalyzeDiskUsageShardResponse resp) {
110111
++successfulShards;
111112
combined.compute(resp.getIndex(), (k, v) -> v == null ? resp.stats : v.add(resp.stats));
112-
} else if (r instanceof DefaultShardOperationFailedException) {
113-
shardFailures.add((DefaultShardOperationFailedException) r);
113+
} else if (r instanceof DefaultShardOperationFailedException e) {
114+
shardFailures.add(e);
115+
} else if (r instanceof Exception e) {
116+
shardFailures.add(new DefaultShardOperationFailedException(ExceptionsHelper.convertToElastic(e)));
114117
} else {
115118
assert false : "unknown response [" + r + "]";
116119
throw new IllegalStateException("unknown response [" + r + "]");

0 commit comments

Comments
 (0)