From 932a7e31129bc4679f1e87d66ae6e05ce4479a12 Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Mon, 23 Mar 2020 19:13:31 +0100 Subject: [PATCH] Backport of async search changes (#53976) * Get Async Search: omit _clusters section when empty (#53907) The _clusters section is omitted by the search API whenever no remote clusters are searched. Async search should do the same, but Get Async Search returns a deserialized response, hence a weird `_clusters` section with all values set to `0` gets returned instead. In fact the recreated Clusters object is not the same object as the EMPTY constant, yet it has the same content. This commit addresses this by changing the comparison in the `toXContent` method to not print out the section if the number of total clusters is `0`. * Async search: remove version from response (#53960) The goal of the version field was to quickly show when you can expect to find something new in the search response, compared to when nothing has changed. This can also be done by looking at the `_shards` section and `num_reduce_phases` returned with the search response. In fact when there has been one or more additional reduction of the results, you can expect new results in the search response. Otherwise, the `_shards` section could notify of additional failures of shards that have completed the query, but that is not a guarantee that their results will be exposed (only when the following partial reduction is performed their results will be available). That said this commit clarifies this in the docs and removes the version field from the async search response * Async Search: replicas to auto expand from 0 to 1 (#53964) This way single node clusters that are green don't go yellow once async search is used, while all the others still have one replica. * [DOCS] address timing issue in async search docs tests (#53910) The docs snippets for submit async search have proven difficult to test as it is not possible to guarantee that you get a response that is not final, even when providing `wait_for_completion=0`. In the docs we want to show though a proper long-running query, and its first response should be partial rather than final. With this commit we adapt the docs snippets to show a partial response, and replace under the hood all that's needed to make the snippets tests succeed when we get a final response. Also, increased the timeout so we always get a final response. Closes #53887 Closes #53891 --- .../asyncsearch/AsyncSearchResponse.java | 40 ++++++----------- .../client/asyncsearch/AsyncSearchIT.java | 1 - .../asyncsearch/AsyncSearchResponseTests.java | 4 +- docs/reference/search/async-search.asciidoc | 43 ++++++++++--------- .../action/search/SearchResponse.java | 6 +-- .../action/search/SearchResponseTests.java | 10 +++++ .../xpack/search/AsyncSearchIndexService.java | 6 +-- .../xpack/search/MutableSearchResponse.java | 9 +--- .../search/AsyncSearchIndexServiceTests.java | 16 +++++++ .../search/AsyncSearchResponseTests.java | 7 ++- .../search/action/AsyncSearchResponse.java | 19 +------- .../test/async_search/10_basic.yml | 9 ++-- 12 files changed, 78 insertions(+), 92 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/asyncsearch/AsyncSearchResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/asyncsearch/AsyncSearchResponse.java index 47dd444ea54..07d3ce81fea 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/asyncsearch/AsyncSearchResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/asyncsearch/AsyncSearchResponse.java @@ -41,7 +41,6 @@ import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpect public class AsyncSearchResponse implements ToXContentObject { @Nullable private final String id; - private final int version; @Nullable private final SearchResponse searchResponse; @Nullable @@ -55,15 +54,13 @@ public class AsyncSearchResponse implements ToXContentObject { /** * Creates an {@link AsyncSearchResponse} with the arguments that are always present in the server response */ - AsyncSearchResponse(int version, - boolean isPartial, - boolean isRunning, - long startTimeMillis, - long expirationTimeMillis, - @Nullable String id, - @Nullable SearchResponse searchResponse, - @Nullable ElasticsearchException error) { - this.version = version; + AsyncSearchResponse(boolean isPartial, + boolean isRunning, + long startTimeMillis, + long expirationTimeMillis, + @Nullable String id, + @Nullable SearchResponse searchResponse, + @Nullable ElasticsearchException error) { this.isPartial = isPartial; this.isRunning = isRunning; this.startTimeMillis = startTimeMillis; @@ -81,13 +78,6 @@ public class AsyncSearchResponse implements ToXContentObject { return id; } - /** - * Returns the version of this response. - */ - public int getVersion() { - return version; - } - /** * Returns the current {@link SearchResponse} or null if not available. * @@ -145,7 +135,6 @@ public class AsyncSearchResponse implements ToXContentObject { if (id != null) { builder.field("id", id); } - builder.field("version", version); builder.field("is_partial", isPartial); builder.field("is_running", isRunning); builder.field("start_time_in_millis", startTimeMillis); @@ -165,7 +154,6 @@ public class AsyncSearchResponse implements ToXContentObject { } public static final ParseField ID_FIELD = new ParseField("id"); - public static final ParseField VERSION_FIELD = new ParseField("version"); public static final ParseField IS_PARTIAL_FIELD = new ParseField("is_partial"); public static final ParseField IS_RUNNING_FIELD = new ParseField("is_running"); public static final ParseField START_TIME_FIELD = new ParseField("start_time_in_millis"); @@ -176,16 +164,14 @@ public class AsyncSearchResponse implements ToXContentObject { public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( "submit_async_search_response", true, args -> new AsyncSearchResponse( - (int) args[0], + (boolean) args[0], (boolean) args[1], - (boolean) args[2], + (long) args[2], (long) args[3], - (long) args[4], - (String) args[5], - (SearchResponse) args[6], - (ElasticsearchException) args[7])); + (String) args[4], + (SearchResponse) args[5], + (ElasticsearchException) args[6])); static { - PARSER.declareInt(constructorArg(), VERSION_FIELD); PARSER.declareBoolean(constructorArg(), IS_PARTIAL_FIELD); PARSER.declareBoolean(constructorArg(), IS_RUNNING_FIELD); PARSER.declareLong(constructorArg(), START_TIME_FIELD); @@ -203,7 +189,7 @@ public class AsyncSearchResponse implements ToXContentObject { return SearchResponse.innerFromXContent(p); } - public static AsyncSearchResponse fromXContent(XContentParser parser) throws IOException { + public static AsyncSearchResponse fromXContent(XContentParser parser) { return PARSER.apply(parser, null); } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/asyncsearch/AsyncSearchIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/asyncsearch/AsyncSearchIT.java index a1c608b3c6e..d0f6ddc9308 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/asyncsearch/AsyncSearchIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/asyncsearch/AsyncSearchIT.java @@ -40,7 +40,6 @@ public class AsyncSearchIT extends ESRestHighLevelClientTestCase { // 15 sec should be enough to make sure we always complete right away request.setWaitForCompletion(new TimeValue(15, TimeUnit.SECONDS)); AsyncSearchResponse response = highLevelClient().asyncSearch().submitAsyncSearch(request, RequestOptions.DEFAULT); - assertTrue(response.getVersion() >= 0); assertFalse(response.isPartial()); assertTrue(response.getStartTime() > 0); assertTrue(response.getExpirationTime() > 0); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/asyncsearch/AsyncSearchResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/asyncsearch/AsyncSearchResponseTests.java index 6caf69db9ac..08c0da25e5b 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/asyncsearch/AsyncSearchResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/asyncsearch/AsyncSearchResponseTests.java @@ -36,7 +36,6 @@ public class AsyncSearchResponseTests @Override protected org.elasticsearch.xpack.core.search.action.AsyncSearchResponse createServerTestInstance(XContentType xContentType) { - int version = randomIntBetween(0, Integer.MAX_VALUE); boolean isPartial = randomBoolean(); boolean isRunning = randomBoolean(); long startTimeMillis = randomLongBetween(0, Long.MAX_VALUE); @@ -48,7 +47,7 @@ public class AsyncSearchResponseTests : new SearchResponse(InternalSearchResponse.empty(), randomAlphaOfLength(10), 1, 1, 0, randomIntBetween(0, 10000), ShardSearchFailure.EMPTY_ARRAY, Clusters.EMPTY); org.elasticsearch.xpack.core.search.action.AsyncSearchResponse testResponse = - new org.elasticsearch.xpack.core.search.action.AsyncSearchResponse(id, version, searchResponse, error, isPartial, isRunning, + new org.elasticsearch.xpack.core.search.action.AsyncSearchResponse(id, searchResponse, error, isPartial, isRunning, startTimeMillis, expirationTimeMillis); return testResponse; } @@ -62,7 +61,6 @@ public class AsyncSearchResponseTests protected void assertInstances(org.elasticsearch.xpack.core.search.action.AsyncSearchResponse expected, AsyncSearchResponse parsed) { assertNotSame(parsed, expected); assertEquals(expected.getId(), parsed.getId()); - assertEquals(expected.getVersion(), parsed.getVersion()); assertEquals(expected.isRunning(), parsed.isRunning()); assertEquals(expected.isPartial(), parsed.isPartial()); assertEquals(expected.getStartTime(), parsed.getStartTime()); diff --git a/docs/reference/search/async-search.asciidoc b/docs/reference/search/async-search.asciidoc index b5df771b643..7f5957a94e4 100644 --- a/docs/reference/search/async-search.asciidoc +++ b/docs/reference/search/async-search.asciidoc @@ -30,9 +30,8 @@ POST /sales*/_async_search?size=0 } } -------------------------------------------------- -// TEST[skip:"AwaitsFix https://github.com/elastic/elasticsearch/issues/53891"] // TEST[setup:sales] -// TEST[s/size=0/size=0&wait_for_completion=0/] +// TEST[s/size=0/size=0&wait_for_completion=10s&clean_on_completion=false/] The response contains an identifier of the search being executed. You can use this ID to later retrieve the search's final results. @@ -43,7 +42,6 @@ results are returned as part of the <> obje -------------------------------------------------- { "id" : "FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=", <1> - "version" : 0, "is_partial" : true, <2> "is_running" : true, <3> "start_time_in_millis" : 1583945890986, @@ -70,12 +68,17 @@ results are returned as part of the <> obje } -------------------------------------------------- // TESTRESPONSE[s/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=/$body.id/] +// TESTRESPONSE[s/"is_partial" : true/"is_partial": $body.is_partial/] +// TESTRESPONSE[s/"is_running" : true/"is_running": $body.is_running/] // TESTRESPONSE[s/1583945890986/$body.start_time_in_millis/] // TESTRESPONSE[s/1584377890986/$body.expiration_time_in_millis/] // TESTRESPONSE[s/"took" : 1122/"took": $body.response.took/] +// TESTRESPONSE[s/"num_reduce_phases" : 0,//] // TESTRESPONSE[s/"total" : 562/"total": $body.response._shards.total/] // TESTRESPONSE[s/"successful" : 3/"successful": $body.response._shards.successful/] // TESTRESPONSE[s/"value" : 157483/"value": $body.response.hits.total.value/] +// TESTRESPONSE[s/"relation" : "gte"/"relation": $body.response.hits.total.relation/] +// TESTRESPONSE[s/"hits" : \[ \]\n\s\s\s\s\}/"hits" : \[\]},"aggregations": $body.response.aggregations/] <1> Identifier of the async search that can be used to monitor its progress, retrieve its results, and/or delete it. <2> Whether the returned search results are partial or final @@ -135,17 +138,16 @@ GET /_async_search/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsd -------------------------------------------------- { "id" : "FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=", - "version" : 2, <1> - "is_partial" : true, <2> - "is_running" : true, <3> + "is_partial" : true, <1> + "is_running" : true, <2> "start_time_in_millis" : 1583945890986, - "expiration_time_in_millis" : 1584377890986, <4> + "expiration_time_in_millis" : 1584377890986, <3> "response" : { "took" : 12144, "timed_out" : false, - "num_reduce_phases" : 38, + "num_reduce_phases" : 46, <4> "_shards" : { - "total" : 562, + "total" : 562, <5> "successful" : 188, "skipped" : 0, "failed" : 0 @@ -158,7 +160,7 @@ GET /_async_search/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsd "max_score" : null, "hits" : [ ] }, - "aggregations" : { <5> + "aggregations" : { <6> "sale_date" : { "buckets" : [] } @@ -176,17 +178,18 @@ GET /_async_search/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsd // TESTRESPONSE[s/"successful" : 188/"successful": $body.response._shards.successful/] // TESTRESPONSE[s/"value" : 456433/"value": $body.response.hits.total.value/] // TESTRESPONSE[s/"buckets" : \[\]/"buckets": $body.response.aggregations.sale_date.buckets/] -// TESTRESPONSE[s/"num_reduce_phases" : 38,//] +// TESTRESPONSE[s/"num_reduce_phases" : 46,//] -<1> The returned `version` is useful to identify whether the response contains -additional results compared to previously obtained responses. If the version -stays the same, no new results have become available, otherwise a higher version -number indicates that more shards have completed their execution of the query -and their partial results are also included in the response. -<2> Whether the returned search results are partial or final -<3> Whether the search is still being executed or it has completed -<4> When the async search will expire -<5> Partial aggregations results, coming from the shards that have already +<1> Whether the returned search results are partial or final +<2> Whether the search is still being executed or it has completed +<3> When the async search will expire +<4> Indicates how many reduction of the results have been performed. If this +number increases compared to the last retrieved results, you can expect +additional results included in the search response +<5> Indicates how many shards have executed the query. Note that in order for +shard results to be included in the search response, they need to be reduced +first. +<6> Partial aggregations results, coming from the shards that have already completed the execution of the query. The `wait_for_completion` parameter, which defaults to `1`, can also be provided diff --git a/server/src/main/java/org/elasticsearch/action/search/SearchResponse.java b/server/src/main/java/org/elasticsearch/action/search/SearchResponse.java index 1c47cc847d7..f8ad1261e3f 100644 --- a/server/src/main/java/org/elasticsearch/action/search/SearchResponse.java +++ b/server/src/main/java/org/elasticsearch/action/search/SearchResponse.java @@ -420,9 +420,7 @@ public class SearchResponse extends ActionResponse implements StatusToXContentOb } private Clusters(StreamInput in) throws IOException { - this.total = in.readVInt(); - this.successful = in.readVInt(); - this.skipped = in.readVInt(); + this(in.readVInt(), in.readVInt(), in.readVInt()); } @Override @@ -434,7 +432,7 @@ public class SearchResponse extends ActionResponse implements StatusToXContentOb @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - if (this != EMPTY) { + if (total > 0) { builder.startObject(_CLUSTERS_FIELD.getPreferredName()); builder.field(TOTAL_FIELD.getPreferredName(), total); builder.field(SUCCESSFUL_FIELD.getPreferredName(), successful); diff --git a/server/src/test/java/org/elasticsearch/action/search/SearchResponseTests.java b/server/src/test/java/org/elasticsearch/action/search/SearchResponseTests.java index ed5104cabe5..299f1212e55 100644 --- a/server/src/test/java/org/elasticsearch/action/search/SearchResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/search/SearchResponseTests.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.text.Text; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; @@ -292,4 +293,13 @@ public class SearchResponseTests extends ESTestCase { assertEquals(searchResponse.getSkippedShards(), deserialized.getSkippedShards()); assertEquals(searchResponse.getClusters(), deserialized.getClusters()); } + + public void testToXContentEmptyClusters() throws IOException { + SearchResponse searchResponse = new SearchResponse(InternalSearchResponse.empty(), null, 1, 1, 0, 1, + ShardSearchFailure.EMPTY_ARRAY, SearchResponse.Clusters.EMPTY); + SearchResponse deserialized = copyWriteable(searchResponse, namedWriteableRegistry, SearchResponse::new, Version.CURRENT); + XContentBuilder builder = XContentBuilder.builder(XContentType.JSON.xContent()); + deserialized.getClusters().toXContent(builder, ToXContent.EMPTY_PARAMS); + assertEquals(0, Strings.toString(builder).length()); + } } diff --git a/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/AsyncSearchIndexService.java b/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/AsyncSearchIndexService.java index b9badfe8443..b94b8900e1f 100644 --- a/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/AsyncSearchIndexService.java +++ b/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/AsyncSearchIndexService.java @@ -66,14 +66,14 @@ class AsyncSearchIndexService { public static final String EXPIRATION_TIME_FIELD = "expiration_time"; public static final String RESULT_FIELD = "result"; - public static Settings settings() { + private static Settings settings() { return Settings.builder() .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) - .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1) + .put(IndexMetaData.SETTING_AUTO_EXPAND_REPLICAS, "0-1") .build(); } - public static XContentBuilder mappings() throws IOException { + private static XContentBuilder mappings() throws IOException { XContentBuilder builder = jsonBuilder() .startObject() .startObject(SINGLE_MAPPING_NAME) diff --git a/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/MutableSearchResponse.java b/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/MutableSearchResponse.java index 8471dac8bbc..6666dc8d7c4 100644 --- a/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/MutableSearchResponse.java +++ b/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/MutableSearchResponse.java @@ -40,7 +40,6 @@ class MutableSearchResponse { private final AtomicArray shardFailures; private final Supplier aggReduceContextSupplier; - private int version; private boolean isPartial; private boolean isFinalReduce; private int successfulShards; @@ -63,7 +62,6 @@ class MutableSearchResponse { this.skippedShards = skippedShards; this.clusters = clusters; this.aggReduceContextSupplier = aggReduceContextSupplier; - this.version = 0; this.shardFailures = totalShards == -1 ? null : new AtomicArray<>(totalShards-skippedShards); this.isPartial = true; this.sections = totalShards == -1 ? null : new InternalSearchResponse( @@ -83,7 +81,6 @@ class MutableSearchResponse { throw new IllegalStateException("received partial response out of order: " + newSections.getNumReducePhases() + " < " + sections.getNumReducePhases()); } - ++ version; this.successfulShards = successfulShards; this.sections = newSections; this.isPartial = true; @@ -96,7 +93,6 @@ class MutableSearchResponse { */ synchronized void updateFinalResponse(int successfulShards, SearchResponseSections newSections) { failIfFrozen(); - ++ version; this.successfulShards = successfulShards; this.sections = newSections; this.isPartial = false; @@ -110,7 +106,6 @@ class MutableSearchResponse { */ synchronized void updateWithFailure(Exception exc) { failIfFrozen(); - ++ version; this.isPartial = true; this.failure = ElasticsearchException.guessRootCauses(exc)[0]; this.frozen = true; @@ -147,7 +142,7 @@ class MutableSearchResponse { } else { resp = null; } - return new AsyncSearchResponse(task.getSearchId().getEncoded(), version, resp, failure, isPartial, + return new AsyncSearchResponse(task.getSearchId().getEncoded(), resp, failure, isPartial, frozen == false, task.getStartTime(), expirationTime); } @@ -159,7 +154,7 @@ class MutableSearchResponse { private ShardSearchFailure[] buildShardFailures() { if (shardFailures == null) { - return new ShardSearchFailure[0]; + return ShardSearchFailure.EMPTY_ARRAY; } List failures = new ArrayList<>(); for (int i = 0; i < shardFailures.length(); i++) { diff --git a/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/AsyncSearchIndexServiceTests.java b/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/AsyncSearchIndexServiceTests.java index afc7627b2e4..c66c61f9343 100644 --- a/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/AsyncSearchIndexServiceTests.java +++ b/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/AsyncSearchIndexServiceTests.java @@ -5,6 +5,10 @@ */ package org.elasticsearch.xpack.search; +import org.elasticsearch.action.admin.indices.get.GetIndexRequest; +import org.elasticsearch.action.admin.indices.get.GetIndexResponse; +import org.elasticsearch.action.support.PlainActionFuture; +import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; @@ -17,6 +21,7 @@ import org.junit.Before; import java.io.IOException; import java.util.Collections; +import java.util.concurrent.ExecutionException; import static org.elasticsearch.xpack.search.AsyncSearchResponseTests.assertEqualResponses; import static org.elasticsearch.xpack.search.AsyncSearchResponseTests.randomAsyncSearchResponse; @@ -100,4 +105,15 @@ public class AsyncSearchIndexServiceTests extends ESSingleNodeTestCase { assertFalse(indexService.ensureAuthenticatedUserIsSame(original, runAsDiffType)); assertFalse(indexService.ensureAuthenticatedUserIsSame(threadContext.getHeaders(), runAsDiffType)); } + + public void testSettings() throws ExecutionException, InterruptedException { + PlainActionFuture future = PlainActionFuture.newFuture(); + indexService.createIndexIfNecessary(future); + future.get(); + GetIndexResponse getIndexResponse = client().admin().indices().getIndex( + new GetIndexRequest().indices(AsyncSearchIndexService.INDEX)).actionGet(); + Settings settings = getIndexResponse.getSettings().get(AsyncSearchIndexService.INDEX); + assertEquals("1", settings.get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)); + assertEquals("0-1", settings.get(IndexMetaData.SETTING_AUTO_EXPAND_REPLICAS)); + } } diff --git a/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/AsyncSearchResponseTests.java b/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/AsyncSearchResponseTests.java index 6c91de0bfa4..97646236004 100644 --- a/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/AsyncSearchResponseTests.java +++ b/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/AsyncSearchResponseTests.java @@ -91,15 +91,15 @@ public class AsyncSearchResponseTests extends ESTestCase { int rand = randomIntBetween(0, 2); switch (rand) { case 0: - return new AsyncSearchResponse(searchId, randomIntBetween(0, Integer.MAX_VALUE), randomBoolean(), + return new AsyncSearchResponse(searchId, randomBoolean(), randomBoolean(), randomNonNegativeLong(), randomNonNegativeLong()); case 1: - return new AsyncSearchResponse(searchId, randomIntBetween(0, Integer.MAX_VALUE), searchResponse, null, + return new AsyncSearchResponse(searchId, searchResponse, null, randomBoolean(), randomBoolean(), randomNonNegativeLong(), randomNonNegativeLong()); case 2: - return new AsyncSearchResponse(searchId, randomIntBetween(0, Integer.MAX_VALUE), searchResponse, + return new AsyncSearchResponse(searchId, searchResponse, new ElasticsearchException(new IOException("boum")), randomBoolean(), randomBoolean(), randomNonNegativeLong(), randomNonNegativeLong()); @@ -120,7 +120,6 @@ public class AsyncSearchResponseTests extends ESTestCase { static void assertEqualResponses(AsyncSearchResponse expected, AsyncSearchResponse actual) { assertEquals(expected.getId(), actual.getId()); - assertEquals(expected.getVersion(), actual.getVersion()); assertEquals(expected.status(), actual.status()); assertEquals(expected.getFailure() == null, actual.getFailure() == null); assertEquals(expected.isRunning(), actual.isRunning()); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/AsyncSearchResponse.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/AsyncSearchResponse.java index 80d1439f80a..ad46baf8918 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/AsyncSearchResponse.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/AsyncSearchResponse.java @@ -25,7 +25,6 @@ import static org.elasticsearch.rest.RestStatus.OK; public class AsyncSearchResponse extends ActionResponse implements StatusToXContentObject { @Nullable private final String id; - private final int version; @Nullable private final SearchResponse searchResponse; @Nullable @@ -40,19 +39,17 @@ public class AsyncSearchResponse extends ActionResponse implements StatusToXCont * Creates an {@link AsyncSearchResponse} with meta-information only (not-modified). */ public AsyncSearchResponse(String id, - int version, boolean isPartial, boolean isRunning, long startTimeMillis, long expirationTimeMillis) { - this(id, version, null, null, isPartial, isRunning, startTimeMillis, expirationTimeMillis); + this(id, null, null, isPartial, isRunning, startTimeMillis, expirationTimeMillis); } /** * Creates a new {@link AsyncSearchResponse} * * @param id The id of the search for further retrieval, null if not stored. - * @param version The version number of this response. * @param searchResponse The actual search response. * @param error The error if the search failed, null if the search is running * or has completed without failure. @@ -61,7 +58,6 @@ public class AsyncSearchResponse extends ActionResponse implements StatusToXCont * @param startTimeMillis The start date of the search in milliseconds since epoch. */ public AsyncSearchResponse(String id, - int version, SearchResponse searchResponse, ElasticsearchException error, boolean isPartial, @@ -69,7 +65,6 @@ public class AsyncSearchResponse extends ActionResponse implements StatusToXCont long startTimeMillis, long expirationTimeMillis) { this.id = id; - this.version = version; this.error = error; this.searchResponse = searchResponse; this.isPartial = isPartial; @@ -80,7 +75,6 @@ public class AsyncSearchResponse extends ActionResponse implements StatusToXCont public AsyncSearchResponse(StreamInput in) throws IOException { this.id = in.readOptionalString(); - this.version = in.readVInt(); this.error = in.readOptionalWriteable(ElasticsearchException::new); this.searchResponse = in.readOptionalWriteable(SearchResponse::new); this.isPartial = in.readBoolean(); @@ -92,7 +86,6 @@ public class AsyncSearchResponse extends ActionResponse implements StatusToXCont @Override public void writeTo(StreamOutput out) throws IOException { out.writeOptionalString(id); - out.writeVInt(version); out.writeOptionalWriteable(error); out.writeOptionalWriteable(searchResponse); out.writeBoolean(isPartial); @@ -102,7 +95,7 @@ public class AsyncSearchResponse extends ActionResponse implements StatusToXCont } public AsyncSearchResponse clone(String id) { - return new AsyncSearchResponse(id, version, searchResponse, error, isPartial, false, startTimeMillis, expirationTimeMillis); + return new AsyncSearchResponse(id, searchResponse, error, isPartial, false, startTimeMillis, expirationTimeMillis); } /** @@ -113,13 +106,6 @@ public class AsyncSearchResponse extends ActionResponse implements StatusToXCont return id; } - /** - * Returns the version of this response. - */ - public int getVersion() { - return version; - } - /** * Returns the current {@link SearchResponse} or null if not available. * @@ -189,7 +175,6 @@ public class AsyncSearchResponse extends ActionResponse implements StatusToXCont if (id != null) { builder.field("id", id); } - builder.field("version", version); builder.field("is_partial", isPartial); builder.field("is_running", isRunning); builder.field("start_time_in_millis", startTimeMillis); diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/test/async_search/10_basic.yml b/x-pack/plugin/src/test/resources/rest-api-spec/test/async_search/10_basic.yml index 292e3bd6cce..c373217b06c 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/test/async_search/10_basic.yml +++ b/x-pack/plugin/src/test/resources/rest-api-spec/test/async_search/10_basic.yml @@ -54,7 +54,6 @@ sort: max - is_false: id - - match: { version: 6 } - match: { is_partial: false } - length: { response.hits.hits: 3 } - match: { response.hits.hits.0._source.max: 1 } @@ -73,8 +72,6 @@ field: max sort: max - - set: { id: id } - - match: { version: 6 } - match: { is_partial: false } - length: { response.hits.hits: 3 } - match: { response.hits.hits.0._source.max: 1 } @@ -96,8 +93,8 @@ sort: max - set: { id: id } - - match: { version: 6 } - match: { is_partial: false } + - is_false: response._clusters - length: { response.hits.hits: 3 } - match: { response.hits.hits.0._source.max: 1 } - match: { response.aggregations.max#max.value: 3.0 } @@ -106,8 +103,8 @@ async_search.get: id: "$id" - - match: { version: 6 } - match: { is_partial: false } + - is_false: response._clusters - length: { response.hits.hits: 3 } - match: { response.hits.hits.0._source.max: 1 } - match: { response.aggregations.max.value: 3.0 } @@ -118,8 +115,8 @@ id: "$id" typed_keys: true - - match: { version: 6 } - match: { is_partial: false } + - is_false: response._clusters - length: { response.hits.hits: 3 } - match: { response.hits.hits.0._source.max: 1 } - match: { response.aggregations.max#max.value: 3.0 }