Improve 404 on missing scroll id
This relates to #6040, the fix is twofold, first, not handling missing context specifically in the search code, but behave the same as we do in non scroll search, where if all the shards failed, raise an exception. The second is to apply this logic in both scroll cases.
This commit is contained in:
parent
7b0efcbd96
commit
44fd962a9f
|
@ -181,9 +181,13 @@ public class TransportSearchScrollQueryAndFetchAction extends AbstractComponent
|
||||||
addShardFailure(shardIndex, new ShardSearchFailure(t));
|
addShardFailure(shardIndex, new ShardSearchFailure(t));
|
||||||
successfulOps.decrementAndGet();
|
successfulOps.decrementAndGet();
|
||||||
if (counter.decrementAndGet() == 0) {
|
if (counter.decrementAndGet() == 0) {
|
||||||
|
if (successfulOps.get() == 0) {
|
||||||
|
listener.onFailure(new SearchPhaseExecutionException("query_fetch", "all shards failed", buildShardFailures()));
|
||||||
|
} else {
|
||||||
finishHim();
|
finishHim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void finishHim() {
|
private void finishHim() {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -174,13 +174,8 @@ public class TransportSearchScrollQueryThenFetchAction extends AbstractComponent
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable t) {
|
||||||
Throwable cause = ExceptionsHelper.unwrapCause(t);
|
|
||||||
if (cause instanceof SearchContextMissingException) {
|
|
||||||
listener.onFailure(t);
|
|
||||||
} else {
|
|
||||||
onQueryPhaseFailure(shardIndex, counter, searchId, t);
|
onQueryPhaseFailure(shardIndex, counter, searchId, t);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +186,9 @@ public class TransportSearchScrollQueryThenFetchAction extends AbstractComponent
|
||||||
addShardFailure(shardIndex, new ShardSearchFailure(t));
|
addShardFailure(shardIndex, new ShardSearchFailure(t));
|
||||||
successfulOps.decrementAndGet();
|
successfulOps.decrementAndGet();
|
||||||
if (counter.decrementAndGet() == 0) {
|
if (counter.decrementAndGet() == 0) {
|
||||||
|
if (successfulOps.get() == 0) {
|
||||||
|
listener.onFailure(new SearchPhaseExecutionException("query", "all shards failed", buildShardFailures()));
|
||||||
|
} else {
|
||||||
try {
|
try {
|
||||||
executeFetchPhase();
|
executeFetchPhase();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
@ -198,6 +196,7 @@ public class TransportSearchScrollQueryThenFetchAction extends AbstractComponent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void executeFetchPhase() throws Exception {
|
private void executeFetchPhase() throws Exception {
|
||||||
if (useSlowScroll) {
|
if (useSlowScroll) {
|
||||||
|
|
|
@ -291,8 +291,8 @@ public class SearchScrollTests extends ElasticsearchIntegrationTest {
|
||||||
.execute().actionGet();
|
.execute().actionGet();
|
||||||
assertThat(clearResponse.isSucceeded(), equalTo(true));
|
assertThat(clearResponse.isSucceeded(), equalTo(true));
|
||||||
|
|
||||||
assertThrows(client().prepareSearchScroll(searchResponse1.getScrollId()).setScroll(TimeValue.timeValueMinutes(2)), SearchContextMissingException.class);
|
assertThrows(client().prepareSearchScroll(searchResponse1.getScrollId()).setScroll(TimeValue.timeValueMinutes(2)), RestStatus.NOT_FOUND);
|
||||||
assertThrows(client().prepareSearchScroll(searchResponse2.getScrollId()).setScroll(TimeValue.timeValueMinutes(2)), SearchContextMissingException.class);
|
assertThrows(client().prepareSearchScroll(searchResponse2.getScrollId()).setScroll(TimeValue.timeValueMinutes(2)), RestStatus.NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -397,8 +397,8 @@ public class SearchScrollTests extends ElasticsearchIntegrationTest {
|
||||||
.execute().actionGet();
|
.execute().actionGet();
|
||||||
assertThat(clearResponse.isSucceeded(), equalTo(true));
|
assertThat(clearResponse.isSucceeded(), equalTo(true));
|
||||||
|
|
||||||
assertThrows(cluster().transportClient().prepareSearchScroll(searchResponse1.getScrollId()).setScroll(TimeValue.timeValueMinutes(2)), SearchContextMissingException.class);
|
assertThrows(cluster().transportClient().prepareSearchScroll(searchResponse1.getScrollId()).setScroll(TimeValue.timeValueMinutes(2)), RestStatus.NOT_FOUND);
|
||||||
assertThrows(cluster().transportClient().prepareSearchScroll(searchResponse2.getScrollId()).setScroll(TimeValue.timeValueMinutes(2)), SearchContextMissingException.class);
|
assertThrows(cluster().transportClient().prepareSearchScroll(searchResponse2.getScrollId()).setScroll(TimeValue.timeValueMinutes(2)), RestStatus.NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -436,17 +436,12 @@ public class SearchScrollTests extends ElasticsearchIntegrationTest {
|
||||||
client().prepareIndex("index", "type", "1").setSource("field", "value").execute().get();
|
client().prepareIndex("index", "type", "1").setSource("field", "value").execute().get();
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
try {
|
|
||||||
SearchResponse searchResponse = client().prepareSearch("index").setSize(1).setScroll("1m").get();
|
SearchResponse searchResponse = client().prepareSearch("index").setSize(1).setScroll("1m").get();
|
||||||
assertThat(searchResponse.getScrollId(), is(notNullValue()));
|
assertThat(searchResponse.getScrollId(), is(notNullValue()));
|
||||||
|
|
||||||
ClearScrollResponse clearScrollResponse = client().prepareClearScroll().addScrollId(searchResponse.getScrollId()).get();
|
ClearScrollResponse clearScrollResponse = client().prepareClearScroll().addScrollId(searchResponse.getScrollId()).get();
|
||||||
assertThat(clearScrollResponse.isSucceeded(), is(true));
|
assertThat(clearScrollResponse.isSucceeded(), is(true));
|
||||||
|
|
||||||
cluster().transportClient().prepareSearchScroll(searchResponse.getScrollId()).get();
|
assertThrows(cluster().transportClient().prepareSearchScroll(searchResponse.getScrollId()), RestStatus.NOT_FOUND);
|
||||||
fail("Expected exception to happen due to non-existing scroll id");
|
|
||||||
} catch (ElasticsearchException e) {
|
|
||||||
assertThat(e.status(), is(RestStatus.NOT_FOUND));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.ElasticsearchIllegalStateException;
|
import org.elasticsearch.ElasticsearchIllegalStateException;
|
||||||
|
import org.elasticsearch.ExceptionsHelper;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.action.ActionFuture;
|
import org.elasticsearch.action.ActionFuture;
|
||||||
import org.elasticsearch.action.ActionRequest;
|
import org.elasticsearch.action.ActionRequest;
|
||||||
|
@ -413,6 +414,35 @@ public class ElasticsearchAssertions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <E extends Throwable> void assertThrows(ActionRequestBuilder<?, ?, ?> builder, RestStatus status) {
|
||||||
|
assertThrows(builder.execute(), status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <E extends Throwable> void assertThrows(ActionRequestBuilder<?, ?, ?> builder, RestStatus status, String extraInfo) {
|
||||||
|
assertThrows(builder.execute(), status, extraInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <E extends Throwable> void assertThrows(ActionFuture future, RestStatus status) {
|
||||||
|
assertThrows(future, status, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void assertThrows(ActionFuture future, RestStatus status, String extraInfo) {
|
||||||
|
boolean fail = false;
|
||||||
|
extraInfo = extraInfo == null || extraInfo.isEmpty() ? "" : extraInfo + ": ";
|
||||||
|
extraInfo += "expected a " + status + " status exception to be thrown";
|
||||||
|
|
||||||
|
try {
|
||||||
|
future.actionGet();
|
||||||
|
fail = true;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
assertThat(extraInfo, ExceptionsHelper.status(e), equalTo(status));
|
||||||
|
}
|
||||||
|
// has to be outside catch clause to get a proper message
|
||||||
|
if (fail) {
|
||||||
|
throw new AssertionError(extraInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static BytesReference serialize(Version version, Streamable streamable) throws IOException {
|
private static BytesReference serialize(Version version, Streamable streamable) throws IOException {
|
||||||
BytesStreamOutput output = new BytesStreamOutput();
|
BytesStreamOutput output = new BytesStreamOutput();
|
||||||
output.setVersion(version);
|
output.setVersion(version);
|
||||||
|
|
Loading…
Reference in New Issue