From 040760d9e4f5aca3a9182a45a20aab4840d37b71 Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Wed, 14 Mar 2018 17:58:16 -0400 Subject: [PATCH 1/7] Fix EsAbortPolicy to conform to API The rejected execution handler API says that rejectedExecution(Runnable, ThreadPoolExecutor) throws a RejectedExecutionException if the task must be rejected due to capacity on the executor. We do throw something that smells like a RejectedExecutionException (it is named EsRejectedExecutionException) yet we violate the API because EsRejectedExecutionException is not a RejectedExecutionException. This has caused problems before where we try to catch RejectedExecution when invoking rejectedExecution but this causes EsRejectedExecutionException to go uncaught. This commit addresses this by modifying EsRejectedExecutionException to extend RejectedExecutionException. Addtionally, we fix an issue with how causes are unwrapped. Without this change, since EsRejectedExecutionException is no longer an ElasticsearchException, the root cause of a rejection would be reported as a remote_transport_exception instead of as an es_rejected_execution_exception. --- .../elasticsearch/ElasticsearchException.java | 5 ++-- .../org/elasticsearch/ExceptionsHelper.java | 3 +++ .../common/io/stream/StreamInput.java | 4 +++ .../common/io/stream/StreamOutput.java | 5 ++++ .../EsRejectedExecutionException.java | 25 ++----------------- .../ElasticsearchExceptionTests.java | 12 +++++++++ .../ExceptionSerializationTests.java | 2 +- 7 files changed, 29 insertions(+), 27 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/ElasticsearchException.java b/server/src/main/java/org/elasticsearch/ElasticsearchException.java index ed20f52754dd4..7addcd053418c 100644 --- a/server/src/main/java/org/elasticsearch/ElasticsearchException.java +++ b/server/src/main/java/org/elasticsearch/ElasticsearchException.java @@ -616,7 +616,7 @@ public static ElasticsearchException[] guessRootCauses(Throwable t) { if (ex instanceof ElasticsearchException) { return ((ElasticsearchException) ex).guessRootCauses(); } - return new ElasticsearchException[]{new ElasticsearchException(t.getMessage(), t) { + return new ElasticsearchException[]{new ElasticsearchException(ex.getMessage(), ex) { @Override protected String getExceptionName() { return getExceptionName(getCause()); @@ -827,8 +827,7 @@ private enum ElasticsearchExceptionHandle { org.elasticsearch.indices.IndexTemplateMissingException::new, 57, UNKNOWN_VERSION_ADDED), SEND_REQUEST_TRANSPORT_EXCEPTION(org.elasticsearch.transport.SendRequestTransportException.class, org.elasticsearch.transport.SendRequestTransportException::new, 58, UNKNOWN_VERSION_ADDED), - ES_REJECTED_EXECUTION_EXCEPTION(org.elasticsearch.common.util.concurrent.EsRejectedExecutionException.class, - org.elasticsearch.common.util.concurrent.EsRejectedExecutionException::new, 59, UNKNOWN_VERSION_ADDED), + // 59 used to be EsRejectedExecutionException // 60 used to be for EarlyTerminationException // 61 used to be for RoutingValidationException NOT_SERIALIZABLE_EXCEPTION_WRAPPER(org.elasticsearch.common.io.stream.NotSerializableExceptionWrapper.class, diff --git a/server/src/main/java/org/elasticsearch/ExceptionsHelper.java b/server/src/main/java/org/elasticsearch/ExceptionsHelper.java index 05ac4d942b35e..0427685b8ef4f 100644 --- a/server/src/main/java/org/elasticsearch/ExceptionsHelper.java +++ b/server/src/main/java/org/elasticsearch/ExceptionsHelper.java @@ -26,6 +26,7 @@ import org.elasticsearch.action.ShardOperationFailedException; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.logging.Loggers; +import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; import org.elasticsearch.index.Index; import org.elasticsearch.rest.RestStatus; @@ -67,6 +68,8 @@ public static RestStatus status(Throwable t) { return ((ElasticsearchException) t).status(); } else if (t instanceof IllegalArgumentException) { return RestStatus.BAD_REQUEST; + } else if (t instanceof EsRejectedExecutionException) { + return RestStatus.TOO_MANY_REQUESTS; } } return RestStatus.INTERNAL_SERVER_ERROR; diff --git a/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java b/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java index a5f01f74ed70c..6706006a0a008 100644 --- a/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java +++ b/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java @@ -36,6 +36,7 @@ import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.text.Text; +import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; @@ -831,6 +832,9 @@ public T readException() throws IOException { return (T) readStackTrace(new InterruptedException(readOptionalString()), this); case 17: return (T) readStackTrace(new IOException(readOptionalString(), readException()), this); + case 18: + final boolean isExecutorShutdown = readBoolean(); + return (T) readStackTrace(new EsRejectedExecutionException(readOptionalString(), isExecutorShutdown), this); default: throw new IOException("no such exception for id: " + key); } diff --git a/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java b/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java index 98a126e75e5c3..3e9ac72963c92 100644 --- a/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java +++ b/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java @@ -35,6 +35,7 @@ import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.io.stream.Writeable.Writer; import org.elasticsearch.common.text.Text; +import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; import org.joda.time.DateTimeZone; import org.joda.time.ReadableInstant; @@ -852,6 +853,10 @@ public void writeException(Throwable throwable) throws IOException { writeCause = false; } else if (throwable instanceof IOException) { writeVInt(17); + } else if (throwable instanceof EsRejectedExecutionException) { + writeVInt(18); + writeBoolean(((EsRejectedExecutionException) throwable).isExecutorShutdown()); + writeCause = false; } else { ElasticsearchException ex; if (throwable instanceof ElasticsearchException && ElasticsearchException.isRegistered(throwable.getClass(), version)) { diff --git a/server/src/main/java/org/elasticsearch/common/util/concurrent/EsRejectedExecutionException.java b/server/src/main/java/org/elasticsearch/common/util/concurrent/EsRejectedExecutionException.java index a38bbf452b7ed..7174058ab7821 100644 --- a/server/src/main/java/org/elasticsearch/common/util/concurrent/EsRejectedExecutionException.java +++ b/server/src/main/java/org/elasticsearch/common/util/concurrent/EsRejectedExecutionException.java @@ -19,14 +19,9 @@ package org.elasticsearch.common.util.concurrent; -import org.elasticsearch.ElasticsearchException; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.rest.RestStatus; +import java.util.concurrent.RejectedExecutionException; -import java.io.IOException; - -public class EsRejectedExecutionException extends ElasticsearchException { +public class EsRejectedExecutionException extends RejectedExecutionException { private final boolean isExecutorShutdown; @@ -43,22 +38,6 @@ public EsRejectedExecutionException() { this(null, false); } - @Override - public RestStatus status() { - return RestStatus.TOO_MANY_REQUESTS; - } - - public EsRejectedExecutionException(StreamInput in) throws IOException{ - super(in); - isExecutorShutdown = in.readBoolean(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeBoolean(isExecutorShutdown); - } - /** * Checks if the thread pool that rejected the execution was terminated * shortly after the rejection. Its possible that this returns false and the diff --git a/server/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java b/server/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java index aacd8cc6a8847..0b1cd49fe8dcf 100644 --- a/server/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java +++ b/server/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java @@ -35,6 +35,7 @@ import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.collect.Tuple; +import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContent; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -76,6 +77,7 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.Matchers.arrayWithSize; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.startsWith; @@ -161,6 +163,16 @@ public void testGuessRootCause() { assertEquals(foobars[0].getCause().getClass(), IllegalArgumentException.class); assertEquals(foobars[0].getExceptionName(), "illegal_argument_exception"); } + + { + final EsRejectedExecutionException esRejectedExecutionException = new EsRejectedExecutionException("rejected", randomBoolean()); + final RemoteTransportException remoteTransportException = + new RemoteTransportException("node", buildNewFakeTransportAddress(), "action", esRejectedExecutionException); + final ElasticsearchException[] rootCauses = ElasticsearchException.guessRootCauses(remoteTransportException); + assertThat(rootCauses, arrayWithSize(1)); + assertThat(rootCauses[0].getExceptionName(), equalTo("es_rejected_execution_exception")); + assertThat(rootCauses[0].getMessage(), equalTo("rejected")); + } } public void testDeduplicate() throws IOException { diff --git a/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java b/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java index b794ded7f8d03..f9d90ffd7fb59 100644 --- a/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java +++ b/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java @@ -728,7 +728,7 @@ public void testIds() { ids.put(56, org.elasticsearch.common.settings.SettingsException.class); ids.put(57, org.elasticsearch.indices.IndexTemplateMissingException.class); ids.put(58, org.elasticsearch.transport.SendRequestTransportException.class); - ids.put(59, org.elasticsearch.common.util.concurrent.EsRejectedExecutionException.class); + ids.put(59, null); // weas EsRejectedExecutionException, which is no longer an instance of ElasticsearchException ids.put(60, null); // EarlyTerminationException was removed in 6.0 ids.put(61, null); // RoutingValidationException was removed in 5.0 ids.put(62, org.elasticsearch.common.io.stream.NotSerializableExceptionWrapper.class); From 51e61e32e368b5269bb91b03c58e227327df8c0f Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Wed, 14 Mar 2018 20:18:32 -0400 Subject: [PATCH 2/7] Fix test --- .../index/reindex/AsyncBulkByScrollActionTests.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/AsyncBulkByScrollActionTests.java b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/AsyncBulkByScrollActionTests.java index db259de411165..17345f5c85b65 100644 --- a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/AsyncBulkByScrollActionTests.java +++ b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/AsyncBulkByScrollActionTests.java @@ -115,6 +115,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.hasToString; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.lessThanOrEqualTo; @@ -330,7 +331,8 @@ public ScheduledFuture schedule(TimeValue delay, String name, Runnable comman ScrollableHitSource.Response response = new ScrollableHitSource.Response(false, emptyList(), 0, emptyList(), null); simulateScrollResponse(new DummyAsyncBulkByScrollAction(), timeValueNanos(System.nanoTime()), 10, response); ExecutionException e = expectThrows(ExecutionException.class, () -> listener.get()); - assertThat(e.getMessage(), equalTo("EsRejectedExecutionException[test]")); + assertThat(e.getCause(), instanceOf(EsRejectedExecutionException.class)); + assertThat(e.getCause(), hasToString(containsString("test"))); assertThat(client.scrollsCleared, contains(scrollId)); // When the task is rejected we don't increment the throttled timer From dc89fc701a6d339635141dfec13dd2d80b8a9cb9 Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Wed, 14 Mar 2018 20:31:18 -0400 Subject: [PATCH 3/7] Add test --- .../org/elasticsearch/ExceptionsHelperTests.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/server/src/test/java/org/elasticsearch/ExceptionsHelperTests.java b/server/src/test/java/org/elasticsearch/ExceptionsHelperTests.java index 011f5b380ecbd..e4f5d36775d3b 100644 --- a/server/src/test/java/org/elasticsearch/ExceptionsHelperTests.java +++ b/server/src/test/java/org/elasticsearch/ExceptionsHelperTests.java @@ -20,9 +20,18 @@ package org.elasticsearch; import org.apache.commons.codec.DecoderException; +import org.elasticsearch.common.collect.Tuple; +import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; +import org.elasticsearch.index.Index; +import org.elasticsearch.index.shard.ShardId; +import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.ESTestCase; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; import java.util.Optional; +import java.util.stream.Collectors; import static org.elasticsearch.ExceptionsHelper.MAX_ITERATIONS; import static org.elasticsearch.ExceptionsHelper.maybeError; @@ -84,4 +93,9 @@ private void assertError(final Throwable cause, final Error error) { assertThat(maybeError.get(), equalTo(error)); } + public void testStatus() { + assertThat(ExceptionsHelper.status(new IllegalArgumentException("illegal")), equalTo(RestStatus.BAD_REQUEST)); + assertThat(ExceptionsHelper.status(new EsRejectedExecutionException("rejected")), equalTo(RestStatus.TOO_MANY_REQUESTS)); + } + } From 8f2d369bbb35263199ba2fe526b0e6494daa1d2a Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Wed, 14 Mar 2018 20:32:09 -0400 Subject: [PATCH 4/7] Remove imports --- .../test/java/org/elasticsearch/ExceptionsHelperTests.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/ExceptionsHelperTests.java b/server/src/test/java/org/elasticsearch/ExceptionsHelperTests.java index e4f5d36775d3b..5a36b3b5e8583 100644 --- a/server/src/test/java/org/elasticsearch/ExceptionsHelperTests.java +++ b/server/src/test/java/org/elasticsearch/ExceptionsHelperTests.java @@ -20,18 +20,11 @@ package org.elasticsearch; import org.apache.commons.codec.DecoderException; -import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; -import org.elasticsearch.index.Index; -import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.ESTestCase; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; import java.util.Optional; -import java.util.stream.Collectors; import static org.elasticsearch.ExceptionsHelper.MAX_ITERATIONS; import static org.elasticsearch.ExceptionsHelper.maybeError; From b9aca83a55dfab347e0c00d693d139c80520580b Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Thu, 15 Mar 2018 22:00:58 -0400 Subject: [PATCH 5/7] BWC --- .../common/io/stream/StreamInput.java | 7 ++++++ .../common/io/stream/StreamOutput.java | 25 +++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java b/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java index 6706006a0a008..886a61b29c1ae 100644 --- a/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java +++ b/server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java @@ -748,6 +748,13 @@ public T readException() throws IOException { switch (key) { case 0: final int ord = readVInt(); + // TODO: remove the if branch when master is bumped to 8.0.0 + assert Version.CURRENT.major < 8; + if (ord == 59) { + final ElasticsearchException ex = new ElasticsearchException(this); + final boolean isExecutorShutdown = readBoolean(); + return (T) new EsRejectedExecutionException(ex.getMessage(), isExecutorShutdown); + } return (T) ElasticsearchException.readException(this, ord); case 1: String msg1 = readOptionalString(); diff --git a/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java b/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java index 3e9ac72963c92..f52869c5e8054 100644 --- a/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java +++ b/server/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java @@ -854,11 +854,27 @@ public void writeException(Throwable throwable) throws IOException { } else if (throwable instanceof IOException) { writeVInt(17); } else if (throwable instanceof EsRejectedExecutionException) { - writeVInt(18); - writeBoolean(((EsRejectedExecutionException) throwable).isExecutorShutdown()); - writeCause = false; + // TODO: remove the if branch when master is bumped to 8.0.0 + assert Version.CURRENT.major < 8; + if (version.before(Version.V_7_0_0_alpha1)) { + /* + * This is a backwards compatibility layer when speaking to nodes that still treated EsRejectedExceutionException as an + * instance of ElasticsearchException. As such, we serialize this in a way that the receiving node would read this as an + * EsRejectedExecutionException. + */ + final ElasticsearchException ex = new ElasticsearchException(throwable.getMessage()); + writeVInt(0); + writeVInt(59); + ex.writeTo(this); + writeBoolean(((EsRejectedExecutionException) throwable).isExecutorShutdown()); + return; + } else { + writeVInt(18); + writeBoolean(((EsRejectedExecutionException) throwable).isExecutorShutdown()); + writeCause = false; + } } else { - ElasticsearchException ex; + final ElasticsearchException ex; if (throwable instanceof ElasticsearchException && ElasticsearchException.isRegistered(throwable.getClass(), version)) { ex = (ElasticsearchException) throwable; } else { @@ -868,7 +884,6 @@ public void writeException(Throwable throwable) throws IOException { writeVInt(ElasticsearchException.getId(ex.getClass())); ex.writeTo(this); return; - } if (writeMessage) { writeOptionalString(throwable.getMessage()); From 729f96c73068a66ef32c5674628df2d66d9201c9 Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Thu, 15 Mar 2018 22:36:44 -0400 Subject: [PATCH 6/7] Change expected exception --- .../test/resources/rest-api-spec/test/painless/15_update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/15_update.yml b/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/15_update.yml index 20047e7d4825d..67ebe2e130ecb 100644 --- a/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/15_update.yml +++ b/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/15_update.yml @@ -135,6 +135,6 @@ source: "for (def key : params.keySet()) { ctx._source[key] = params[key]}" params: { bar: 'xxx' } - - match: { error.root_cause.0.type: "remote_transport_exception" } + - match: { error.root_cause.0.type: "illegal_argument_exception" } - match: { error.type: "illegal_argument_exception" } - match: { error.reason: "Iterable object is self-referencing itself" } From c6046eb31262ed2e964f49efc6a34c1a5f650f96 Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Fri, 16 Mar 2018 07:52:58 -0400 Subject: [PATCH 7/7] fix tests --- .../rest-api-spec/test/painless/15_update.yml | 2 +- .../java/org/elasticsearch/ElasticsearchException.java | 2 +- .../org/elasticsearch/ElasticsearchExceptionTests.java | 10 ---------- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/15_update.yml b/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/15_update.yml index 67ebe2e130ecb..20047e7d4825d 100644 --- a/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/15_update.yml +++ b/modules/lang-painless/src/test/resources/rest-api-spec/test/painless/15_update.yml @@ -135,6 +135,6 @@ source: "for (def key : params.keySet()) { ctx._source[key] = params[key]}" params: { bar: 'xxx' } - - match: { error.root_cause.0.type: "illegal_argument_exception" } + - match: { error.root_cause.0.type: "remote_transport_exception" } - match: { error.type: "illegal_argument_exception" } - match: { error.reason: "Iterable object is self-referencing itself" } diff --git a/server/src/main/java/org/elasticsearch/ElasticsearchException.java b/server/src/main/java/org/elasticsearch/ElasticsearchException.java index 7addcd053418c..bfa37808402c4 100644 --- a/server/src/main/java/org/elasticsearch/ElasticsearchException.java +++ b/server/src/main/java/org/elasticsearch/ElasticsearchException.java @@ -616,7 +616,7 @@ public static ElasticsearchException[] guessRootCauses(Throwable t) { if (ex instanceof ElasticsearchException) { return ((ElasticsearchException) ex).guessRootCauses(); } - return new ElasticsearchException[]{new ElasticsearchException(ex.getMessage(), ex) { + return new ElasticsearchException[]{new ElasticsearchException(t.getMessage(), t) { @Override protected String getExceptionName() { return getExceptionName(getCause()); diff --git a/server/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java b/server/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java index 0b1cd49fe8dcf..93cc70a547620 100644 --- a/server/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java +++ b/server/src/test/java/org/elasticsearch/ElasticsearchExceptionTests.java @@ -163,16 +163,6 @@ public void testGuessRootCause() { assertEquals(foobars[0].getCause().getClass(), IllegalArgumentException.class); assertEquals(foobars[0].getExceptionName(), "illegal_argument_exception"); } - - { - final EsRejectedExecutionException esRejectedExecutionException = new EsRejectedExecutionException("rejected", randomBoolean()); - final RemoteTransportException remoteTransportException = - new RemoteTransportException("node", buildNewFakeTransportAddress(), "action", esRejectedExecutionException); - final ElasticsearchException[] rootCauses = ElasticsearchException.guessRootCauses(remoteTransportException); - assertThat(rootCauses, arrayWithSize(1)); - assertThat(rootCauses[0].getExceptionName(), equalTo("es_rejected_execution_exception")); - assertThat(rootCauses[0].getMessage(), equalTo("rejected")); - } } public void testDeduplicate() throws IOException {