Skip to content

Commit 0766ad9

Browse files
committed
Fix search scroll request with a plain text body (#23183)
The backport of #22691 caused plain text bodies with a scroll id to fail with an IllegalStateException as the wrong method was being called. This commit adds tests to ensure plain text bodies work and fixes the search scroll action so that it properly handles a request with a plain text body.
1 parent c617849 commit 0766ad9

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

core/src/main/java/org/elasticsearch/rest/action/search/RestSearchScrollAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC
5757
searchScrollRequest.scroll(new Scroll(parseTimeValue(scroll, null, "scroll")));
5858
}
5959

60-
request.withContentOrSourceParamParserOrNull(xContentParser -> {
60+
request.withContentOrSourceParamParserOrNullLenient(xContentParser -> {
6161
if (xContentParser == null) {
6262
if (request.hasContent()) {
6363
// TODO: why do we accept this plain text value? maybe we can just use the scroll params?

core/src/test/java/org/elasticsearch/search/scroll/RestClearScrollActionTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,33 @@
1919

2020
package org.elasticsearch.search.scroll;
2121

22+
import org.elasticsearch.action.ActionListener;
2223
import org.elasticsearch.action.search.ClearScrollRequest;
24+
import org.elasticsearch.client.node.NodeClient;
2325
import org.elasticsearch.common.bytes.BytesArray;
2426
import org.elasticsearch.common.settings.Settings;
27+
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
2528
import org.elasticsearch.common.xcontent.XContentFactory;
2629
import org.elasticsearch.common.xcontent.XContentParser;
2730
import org.elasticsearch.common.xcontent.XContentType;
31+
import org.elasticsearch.rest.RestChannel;
2832
import org.elasticsearch.rest.RestController;
2933
import org.elasticsearch.rest.RestRequest;
3034
import org.elasticsearch.rest.action.search.RestClearScrollAction;
3135
import org.elasticsearch.test.ESTestCase;
3236
import org.elasticsearch.test.rest.FakeRestRequest;
37+
import org.mockito.ArgumentCaptor;
3338

39+
import java.util.Arrays;
40+
import java.util.Collections;
41+
import java.util.List;
42+
import java.util.stream.Collectors;
43+
44+
import static org.elasticsearch.mock.orig.Mockito.verify;
3445
import static org.hamcrest.Matchers.contains;
3546
import static org.hamcrest.Matchers.equalTo;
3647
import static org.hamcrest.Matchers.startsWith;
48+
import static org.mockito.Matchers.any;
3749
import static org.mockito.Mockito.mock;
3850

3951
public class RestClearScrollActionTests extends ESTestCase {
@@ -68,4 +80,19 @@ public void testParseClearScrollRequestWithUnknownParamThrowsException() throws
6880
assertThat(e.getMessage(), startsWith("Unknown parameter [unknown]"));
6981
}
7082

83+
public void testParseClearScrollPlaintext() throws Exception {
84+
RestClearScrollAction action = new RestClearScrollAction(Settings.EMPTY, mock(RestController.class));
85+
NodeClient mockNodeClient = mock(NodeClient.class);
86+
final List<String> scrollIds = Arrays.asList(generateRandomStringArray(4, 30, false, false));
87+
final String content = scrollIds.stream().collect(Collectors.joining(","));
88+
FakeRestRequest fakeRestRequest = new FakeRestRequest.Builder(NamedXContentRegistry.EMPTY)
89+
.withContent(new BytesArray(content), null)
90+
.withHeaders(Collections.singletonMap("Content-Type", Collections.singletonList("text/plain")))
91+
.build();
92+
action.handleRequest(fakeRestRequest, mock(RestChannel.class), mockNodeClient);
93+
ArgumentCaptor<ClearScrollRequest> captor = ArgumentCaptor.forClass(ClearScrollRequest.class);
94+
verify(mockNodeClient).clearScroll(captor.capture(), any(ActionListener.class));
95+
96+
assertEquals(scrollIds, captor.getValue().getScrollIds());
97+
}
7198
}

core/src/test/java/org/elasticsearch/search/scroll/RestSearchScrollActionTests.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,30 @@
1919

2020
package org.elasticsearch.search.scroll;
2121

22+
import org.elasticsearch.action.ActionListener;
2223
import org.elasticsearch.action.search.SearchScrollRequest;
24+
import org.elasticsearch.client.node.NodeClient;
2325
import org.elasticsearch.common.bytes.BytesArray;
2426
import org.elasticsearch.common.settings.Settings;
2527
import org.elasticsearch.common.unit.TimeValue;
28+
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
2629
import org.elasticsearch.common.xcontent.XContentFactory;
2730
import org.elasticsearch.common.xcontent.XContentParser;
2831
import org.elasticsearch.common.xcontent.XContentType;
32+
import org.elasticsearch.rest.RestChannel;
2933
import org.elasticsearch.rest.RestController;
3034
import org.elasticsearch.rest.RestRequest;
3135
import org.elasticsearch.rest.action.search.RestSearchScrollAction;
3236
import org.elasticsearch.test.ESTestCase;
3337
import org.elasticsearch.test.rest.FakeRestRequest;
38+
import org.mockito.ArgumentCaptor;
3439

40+
import java.util.Collections;
41+
42+
import static org.elasticsearch.mock.orig.Mockito.verify;
3543
import static org.hamcrest.Matchers.equalTo;
3644
import static org.hamcrest.Matchers.startsWith;
45+
import static org.mockito.Matchers.any;
3746
import static org.mockito.Mockito.mock;
3847

3948
public class RestSearchScrollActionTests extends ESTestCase {
@@ -71,4 +80,20 @@ public void testParseSearchScrollRequestWithUnknownParamThrowsException() throws
7180
() -> RestSearchScrollAction.buildFromContent(invalidContent, searchScrollRequest));
7281
assertThat(e.getMessage(), startsWith("Unknown parameter [unknown]"));
7382
}
83+
84+
public void testParseSearchScrollPlaintext() throws Exception {
85+
RestSearchScrollAction action = new RestSearchScrollAction(Settings.EMPTY, mock(RestController.class));
86+
NodeClient mockNodeClient = mock(NodeClient.class);
87+
final String scrollId = randomAsciiOfLengthBetween(1, 30);
88+
FakeRestRequest fakeRestRequest = new FakeRestRequest.Builder(NamedXContentRegistry.EMPTY)
89+
.withContent(new BytesArray(scrollId), null)
90+
.withHeaders(Collections.singletonMap("Content-Type", Collections.singletonList("text/plain")))
91+
.build();
92+
action.handleRequest(fakeRestRequest, mock(RestChannel.class), mockNodeClient);
93+
ArgumentCaptor<SearchScrollRequest> captor = ArgumentCaptor.forClass(SearchScrollRequest.class);
94+
verify(mockNodeClient).searchScroll(captor.capture(), any(ActionListener.class));
95+
96+
assertEquals(scrollId, captor.getValue().scrollId());
97+
}
98+
7499
}

0 commit comments

Comments
 (0)