diff --git a/server/src/main/java/org/elasticsearch/action/support/broadcast/BaseBroadcastResponse.java b/server/src/main/java/org/elasticsearch/action/support/broadcast/BaseBroadcastResponse.java index c7e4de245d4d9..f6ad9bdac3c7e 100644 --- a/server/src/main/java/org/elasticsearch/action/support/broadcast/BaseBroadcastResponse.java +++ b/server/src/main/java/org/elasticsearch/action/support/broadcast/BaseBroadcastResponse.java @@ -84,6 +84,13 @@ public int getFailedShards() { return failedShards; } + /** + * The shards that were not available when the request was executed. + */ + public int getUnavailableShards() { + return totalShards - successfulShards - failedShards; + } + /** * The REST status that should be used for the response */ diff --git a/server/src/test/java/org/elasticsearch/action/support/replication/BroadcastReplicationTests.java b/server/src/test/java/org/elasticsearch/action/support/replication/BroadcastReplicationTests.java index 98c83ba796220..45d0ce838e897 100644 --- a/server/src/test/java/org/elasticsearch/action/support/replication/BroadcastReplicationTests.java +++ b/server/src/test/java/org/elasticsearch/action/support/replication/BroadcastReplicationTests.java @@ -167,7 +167,7 @@ public void testNotStartedPrimary() throws InterruptedException, ExecutionExcept response.get(); logger.info("total shards: {}, ", response.get().getTotalShards()); // we expect no failures here because UnavailableShardsException does not count as failed - assertBroadcastResponse(2, 0, 0, response.get(), null); + assertBroadcastResponse(2, 0, 0, 2, response.get(), null); } public void testStartedPrimary() throws InterruptedException, ExecutionException { @@ -194,23 +194,28 @@ public void testResultCombine() throws InterruptedException, ExecutionException, ActionTestUtils.execute(broadcastReplicationAction, null, new DummyBroadcastRequest().indices(index), response); int succeeded = 0; int failed = 0; + int unavailable = 0; for (Tuple> shardRequests : broadcastReplicationAction.capturedShardRequests) { if (randomBoolean()) { ReplicationResponse.ShardInfo.Failure[] failures = new ReplicationResponse.ShardInfo.Failure[0]; int shardsSucceeded = randomInt(1) + 1; succeeded += shardsSucceeded; ReplicationResponse replicationResponse = new ReplicationResponse(); - if (shardsSucceeded == 1 && randomBoolean()) { - // sometimes add failure (no failure means shard unavailable) - failures = new ReplicationResponse.ShardInfo.Failure[1]; - failures[0] = new ReplicationResponse.ShardInfo.Failure( - shardRequests.v1(), - null, - new Exception("pretend shard failed"), - RestStatus.GATEWAY_TIMEOUT, - false - ); - failed++; + if (shardsSucceeded == 1) { + if (randomBoolean()) { + // sometimes add failure (no failure means shard unavailable) + failures = new ReplicationResponse.ShardInfo.Failure[1]; + failures[0] = new ReplicationResponse.ShardInfo.Failure( + shardRequests.v1(), + null, + new Exception("pretend shard failed"), + RestStatus.GATEWAY_TIMEOUT, + false + ); + failed++; + } else { + unavailable++; + } } replicationResponse.setShardInfo(ReplicationResponse.ShardInfo.of(2, shardsSucceeded, failures)); shardRequests.v2().onResponse(replicationResponse); @@ -221,7 +226,7 @@ public void testResultCombine() throws InterruptedException, ExecutionException, shardRequests.v2().onFailure(new Exception("pretend shard failed")); } } - assertBroadcastResponse(2 * numShards, succeeded, failed, response.get(), Exception.class); + assertBroadcastResponse(2 * numShards, succeeded, failed, unavailable, response.get(), Exception.class); } public void testNoShards() throws InterruptedException, ExecutionException, IOException { @@ -338,15 +343,27 @@ public BaseBroadcastResponse executeAndAssertImmediateResponse( return response.actionGet(5, TimeUnit.SECONDS); } - private void assertBroadcastResponse(int total, int successful, int failed, BaseBroadcastResponse response, Class exceptionClass) { + private void assertBroadcastResponse( + int total, + int successful, + int failed, + int unavailable, + BaseBroadcastResponse response, + Class exceptionClass + ) { assertThat(response.getSuccessfulShards(), equalTo(successful)); assertThat(response.getTotalShards(), equalTo(total)); assertThat(response.getFailedShards(), equalTo(failed)); + assertThat(response.getUnavailableShards(), equalTo(unavailable)); for (int i = 0; i < failed; i++) { assertThat(response.getShardFailures()[0].getCause().getCause(), instanceOf(exceptionClass)); } } + private void assertBroadcastResponse(int total, int successful, int failed, BaseBroadcastResponse response, Class exceptionClass) { + assertBroadcastResponse(total, successful, failed, 0, response, exceptionClass); + } + /** * Copy index and routing table from default project to the target project. */