Skip to content

Commit 415c910

Browse files
committed
address review
1 parent 05e2209 commit 415c910

File tree

8 files changed

+123
-20
lines changed

8 files changed

+123
-20
lines changed

server/src/main/java/org/elasticsearch/action/search/SearchRequest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
*/
5858
public class SearchRequest extends ActionRequest implements IndicesRequest.Replaceable {
5959

60-
private static final ToXContent.Params FORMAT_PARAMS = new ToXContent.MapParams(Collections.singletonMap("pretty", "false"));
60+
public static final ToXContent.Params FORMAT_PARAMS = new ToXContent.MapParams(Collections.singletonMap("pretty", "false"));
6161

6262
public static final int DEFAULT_PRE_FILTER_SHARD_SIZE = 128;
6363
public static final int DEFAULT_BATCHED_REDUCE_SIZE = 512;

x-pack/plugin/async-search/qa/rest/src/test/resources/rest-api-spec/test/search/10_basic.yml

+34-2
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@
6767
wait_for_completion: 10s
6868
clean_on_completion: false
6969
body:
70-
query:
71-
match_all: {}
7270
aggs:
7371
1:
7472
max:
@@ -82,6 +80,28 @@
8280
- match: { response.hits.hits.0._source.max: 1 }
8381
- match: { response.aggregations.1.value: 3.0 }
8482

83+
# test with typed_keys:
84+
- do:
85+
async_search.submit:
86+
index: test-*
87+
batched_reduce_size: 2
88+
wait_for_completion: 10s
89+
clean_on_completion: false
90+
typed_keys: true
91+
body:
92+
aggs:
93+
1:
94+
max:
95+
field: max
96+
sort: max
97+
98+
- set: { id: id }
99+
- match: { version: 6 }
100+
- match: { is_partial: false }
101+
- length: { response.hits.hits: 3 }
102+
- match: { response.hits.hits.0._source.max: 1 }
103+
- match: { response.aggregations.max#1.value: 3.0 }
104+
85105
- do:
86106
async_search.get:
87107
id: "$id"
@@ -92,6 +112,18 @@
92112
- match: { response.hits.hits.0._source.max: 1 }
93113
- match: { response.aggregations.1.value: 3.0 }
94114

115+
# test with typed_keys:
116+
- do:
117+
async_search.get:
118+
id: "$id"
119+
typed_keys: true
120+
121+
- match: { version: 6 }
122+
- match: { is_partial: false }
123+
- length: { response.hits.hits: 3 }
124+
- match: { response.hits.hits.0._source.max: 1 }
125+
- match: { response.aggregations.max#1.value: 3.0 }
126+
95127
- do:
96128
async_search.delete:
97129
id: "$id"

x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/RestGetAsyncSearchAction.java

+7-6
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@
55
*/
66
package org.elasticsearch.xpack.search;
77

8-
import org.elasticsearch.action.ActionRequestValidationException;
98
import org.elasticsearch.client.node.NodeClient;
109
import org.elasticsearch.rest.BaseRestHandler;
11-
import org.elasticsearch.rest.RestHandler.Route;
1210
import org.elasticsearch.rest.RestRequest;
1311
import org.elasticsearch.rest.action.RestStatusToXContentListener;
1412
import org.elasticsearch.xpack.core.search.action.GetAsyncSearchAction;
1513

1614
import java.util.List;
15+
import java.util.Set;
1716

1817
import static java.util.Arrays.asList;
1918
import static java.util.Collections.unmodifiableList;
2019
import static org.elasticsearch.rest.RestRequest.Method.GET;
20+
import static org.elasticsearch.xpack.search.RestSubmitAsyncSearchAction.RESPONSE_PARAMS;
2121

2222
public class RestGetAsyncSearchAction extends BaseRestHandler {
2323
@Override
@@ -43,10 +43,11 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
4343
if (request.hasParam("last_version")) {
4444
get.setLastVersion(request.paramAsInt("last_version", get.getLastVersion()));
4545
}
46-
ActionRequestValidationException validationException = get.validate();
47-
if (validationException != null) {
48-
throw validationException;
49-
}
5046
return channel -> client.execute(GetAsyncSearchAction.INSTANCE, get, new RestStatusToXContentListener<>(channel));
5147
}
48+
49+
@Override
50+
protected Set<String> responseParams() {
51+
return RESPONSE_PARAMS;
52+
}
5253
}

x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/RestSubmitAsyncSearchAction.java

+10-6
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
*/
66
package org.elasticsearch.xpack.search;
77

8-
import org.elasticsearch.action.ActionRequestValidationException;
98
import org.elasticsearch.client.node.NodeClient;
109
import org.elasticsearch.rest.BaseRestHandler;
11-
import org.elasticsearch.rest.RestHandler.Route;
1210
import org.elasticsearch.rest.RestRequest;
1311
import org.elasticsearch.rest.action.RestCancellableNodeClient;
1412
import org.elasticsearch.rest.action.RestStatusToXContentListener;
@@ -17,6 +15,8 @@
1715
import org.elasticsearch.xpack.core.search.action.SubmitAsyncSearchRequest;
1816

1917
import java.io.IOException;
18+
import java.util.Collections;
19+
import java.util.Set;
2020
import java.util.function.IntConsumer;
2121
import java.util.List;
2222

@@ -27,6 +27,9 @@
2727
import static org.elasticsearch.rest.action.search.RestSearchAction.parseSearchRequest;
2828

2929
public final class RestSubmitAsyncSearchAction extends BaseRestHandler {
30+
static final String TYPED_KEYS_PARAM = "typed_keys";
31+
static final Set<String> RESPONSE_PARAMS = Collections.singleton(TYPED_KEYS_PARAM);
32+
3033
@Override
3134
public List<Route> routes() {
3235
return unmodifiableList(asList(
@@ -57,14 +60,15 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
5760
if (request.hasParam("clean_on_completion")) {
5861
submit.setCleanOnCompletion(request.paramAsBoolean("clean_on_completion", submit.isCleanOnCompletion()));
5962
}
60-
ActionRequestValidationException validationException = submit.validate();
61-
if (validationException != null) {
62-
throw validationException;
63-
}
6463
return channel -> {
6564
RestStatusToXContentListener<AsyncSearchResponse> listener = new RestStatusToXContentListener<>(channel);
6665
RestCancellableNodeClient cancelClient = new RestCancellableNodeClient(client, request.getHttpChannel());
6766
cancelClient.execute(SubmitAsyncSearchAction.INSTANCE, submit, listener);
6867
};
6968
}
69+
70+
@Override
71+
protected Set<String> responseParams() {
72+
return RESPONSE_PARAMS;
73+
}
7074
}

x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/SubmitAsyncSearchRequestTests.java

+43
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,21 @@
55
*/
66
package org.elasticsearch.xpack.search;
77

8+
import org.elasticsearch.action.ActionRequestValidationException;
89
import org.elasticsearch.action.search.SearchType;
910
import org.elasticsearch.action.support.IndicesOptions;
1011
import org.elasticsearch.common.io.stream.Writeable;
1112
import org.elasticsearch.common.unit.TimeValue;
1213
import org.elasticsearch.index.query.QueryBuilders;
1314
import org.elasticsearch.search.aggregations.AggregationBuilders;
1415
import org.elasticsearch.search.builder.SearchSourceBuilder;
16+
import org.elasticsearch.search.suggest.SuggestBuilder;
1517
import org.elasticsearch.xpack.core.search.action.SubmitAsyncSearchRequest;
1618
import org.elasticsearch.xpack.core.transform.action.AbstractWireSerializingTransformTestCase;
1719

20+
import static org.hamcrest.Matchers.containsString;
21+
import static org.hamcrest.Matchers.equalTo;
22+
1823
public class SubmitAsyncSearchRequestTests extends AbstractWireSerializingTransformTestCase<SubmitAsyncSearchRequest> {
1924
@Override
2025
protected Writeable.Reader<SubmitAsyncSearchRequest> instanceReader() {
@@ -66,4 +71,42 @@ protected SearchSourceBuilder randomSearchSourceBuilder() {
6671
}
6772
return source;
6873
}
74+
75+
public void testValidateCssMinimizeRoundtrips() {
76+
SubmitAsyncSearchRequest req = new SubmitAsyncSearchRequest();
77+
req.getSearchRequest().setCcsMinimizeRoundtrips(true);
78+
ActionRequestValidationException exc = req.validate();
79+
assertNotNull(exc);
80+
assertThat(exc.validationErrors().size(), equalTo(1));
81+
assertThat(exc.validationErrors().get(0), containsString("[ccs_minimize_roundtrips]"));
82+
}
83+
84+
public void testValidateScroll() {
85+
SubmitAsyncSearchRequest req = new SubmitAsyncSearchRequest();
86+
req.getSearchRequest().scroll(TimeValue.timeValueMinutes(5));
87+
ActionRequestValidationException exc = req.validate();
88+
assertNotNull(exc);
89+
assertThat(exc.validationErrors().size(), equalTo(2));
90+
// request_cache is activated by default
91+
assertThat(exc.validationErrors().get(0), containsString("[request_cache]"));
92+
assertThat(exc.validationErrors().get(1), containsString("[scroll]"));
93+
}
94+
95+
public void testValidateKeepAlive() {
96+
SubmitAsyncSearchRequest req = new SubmitAsyncSearchRequest();
97+
req.setKeepAlive(TimeValue.timeValueSeconds(randomIntBetween(1, 59)));
98+
ActionRequestValidationException exc = req.validate();
99+
assertNotNull(exc);
100+
assertThat(exc.validationErrors().size(), equalTo(1));
101+
assertThat(exc.validationErrors().get(0), containsString("[keep_alive]"));
102+
}
103+
104+
public void testValidateSuggestOnly() {
105+
SubmitAsyncSearchRequest req = new SubmitAsyncSearchRequest();
106+
req.getSearchRequest().source(new SearchSourceBuilder().suggest(new SuggestBuilder()));
107+
ActionRequestValidationException exc = req.validate();
108+
assertNotNull(exc);
109+
assertThat(exc.validationErrors().size(), equalTo(1));
110+
assertThat(exc.validationErrors().get(0), containsString("suggest"));
111+
}
69112
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/AsyncSearchResponse.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,10 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
193193
builder.field("start_time_in_millis", startTimeMillis);
194194
builder.field("expiration_time_in_millis", expirationTimeMillis);
195195

196-
builder.field("response", searchResponse);
196+
if (searchResponse != null) {
197+
builder.field("response");
198+
searchResponse.toXContent(builder, params);
199+
}
197200
if (error != null) {
198201
builder.startObject("error");
199202
error.toXContent(builder, params);

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/search/action/SubmitAsyncSearchRequest.java

+20-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.elasticsearch.action.ActionRequest;
99
import org.elasticsearch.action.ActionRequestValidationException;
1010
import org.elasticsearch.action.search.SearchRequest;
11+
import org.elasticsearch.common.Strings;
1112
import org.elasticsearch.common.io.stream.StreamInput;
1213
import org.elasticsearch.common.io.stream.StreamOutput;
1314
import org.elasticsearch.common.unit.TimeValue;
@@ -21,14 +22,15 @@
2122
import java.util.Objects;
2223

2324
import static org.elasticsearch.action.ValidateActions.addValidationError;
25+
import static org.elasticsearch.action.search.SearchRequest.FORMAT_PARAMS;
2426

2527
/**
2628
* A request to track asynchronously the progress of a search against one or more indices.
2729
*
2830
* @see AsyncSearchResponse
2931
*/
3032
public class SubmitAsyncSearchRequest extends ActionRequest {
31-
public static long MIN_KEEP_ALIVE = TimeValue.timeValueHours(1).millis();
33+
public static long MIN_KEEP_ALIVE = TimeValue.timeValueMinutes(1).millis();
3234

3335
private TimeValue waitForCompletion = TimeValue.timeValueSeconds(1);
3436
private boolean cleanOnCompletion = true;
@@ -128,22 +130,26 @@ public boolean isCleanOnCompletion() {
128130
public ActionRequestValidationException validate() {
129131
ActionRequestValidationException validationException = request.validate();
130132
if (request.scroll() != null) {
131-
addValidationError("scroll queries are not supported", validationException);
133+
addValidationError("[scroll] queries are not supported", validationException);
132134
}
133135
if (request.isSuggestOnly()) {
134136
validationException = addValidationError("suggest-only queries are not supported", validationException);
135137
}
136138
if (keepAlive.getMillis() < MIN_KEEP_ALIVE) {
137139
validationException =
138-
addValidationError("keep_alive must be greater than 1 minute, got:" + keepAlive.toString(), validationException);
140+
addValidationError("[keep_alive] must be greater than 1 minute, got:" + keepAlive.toString(), validationException);
141+
}
142+
if (request.isCcsMinimizeRoundtrips()) {
143+
validationException =
144+
addValidationError("[ccs_minimize_roundtrips] is not supported on async search queries", validationException);
139145
}
140146

141147
return validationException;
142148
}
143149

144150
@Override
145151
public Task createTask(long id, String type, String action, TaskId parentTaskId, Map<String, String> headers) {
146-
return new CancellableTask(id, type, action, "", parentTaskId, headers) {
152+
return new CancellableTask(id, type, action, toString(), parentTaskId, headers) {
147153
@Override
148154
public boolean shouldCancelChildrenOnCancellation() {
149155
return true;
@@ -166,4 +172,14 @@ public boolean equals(Object o) {
166172
public int hashCode() {
167173
return Objects.hash(waitForCompletion, cleanOnCompletion, keepAlive, request);
168174
}
175+
176+
@Override
177+
public String toString() {
178+
return "SubmitAsyncSearchRequest{" +
179+
"waitForCompletion=" + waitForCompletion +
180+
", cleanOnCompletion=" + cleanOnCompletion +
181+
", keepAlive=" + keepAlive +
182+
", request=" + request +
183+
'}';
184+
}
169185
}

x-pack/plugin/src/test/resources/rest-api-spec/api/async_search.get.json

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
"keep_alive": {
3333
"type": "time",
3434
"description": "Specify the time that the request should remain reachable in the cluster."
35+
},
36+
"typed_keys":{
37+
"type":"boolean",
38+
"description":"Specify whether aggregation and suggester names should be prefixed by their respective types in the response"
3539
}
3640
}
3741
}

0 commit comments

Comments
 (0)