|
@@ -19,17 +19,51 @@
|
|
|
|
|
|
package org.elasticsearch.client;
|
|
|
|
|
|
+import com.fasterxml.jackson.core.JsonParseException;
|
|
|
import org.apache.http.Header;
|
|
|
+import org.apache.http.HttpEntity;
|
|
|
+import org.apache.http.HttpHost;
|
|
|
+import org.apache.http.HttpResponse;
|
|
|
+import org.apache.http.ProtocolVersion;
|
|
|
+import org.apache.http.RequestLine;
|
|
|
+import org.apache.http.StatusLine;
|
|
|
+import org.apache.http.entity.BasicHttpEntity;
|
|
|
+import org.apache.http.entity.ByteArrayEntity;
|
|
|
+import org.apache.http.entity.ContentType;
|
|
|
+import org.apache.http.entity.StringEntity;
|
|
|
+import org.apache.http.message.BasicHttpResponse;
|
|
|
+import org.apache.http.message.BasicRequestLine;
|
|
|
+import org.apache.http.message.BasicStatusLine;
|
|
|
+import org.elasticsearch.ElasticsearchException;
|
|
|
+import org.elasticsearch.action.ActionListener;
|
|
|
+import org.elasticsearch.action.ActionRequest;
|
|
|
+import org.elasticsearch.action.ActionRequestValidationException;
|
|
|
+import org.elasticsearch.action.main.MainRequest;
|
|
|
+import org.elasticsearch.common.CheckedFunction;
|
|
|
+import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
|
+import org.elasticsearch.common.xcontent.XContentParser;
|
|
|
+import org.elasticsearch.common.xcontent.cbor.CborXContent;
|
|
|
+import org.elasticsearch.common.xcontent.smile.SmileXContent;
|
|
|
+import org.elasticsearch.rest.RestStatus;
|
|
|
import org.elasticsearch.test.ESTestCase;
|
|
|
import org.junit.Before;
|
|
|
import org.mockito.ArgumentMatcher;
|
|
|
+import org.mockito.Matchers;
|
|
|
import org.mockito.internal.matchers.ArrayEquals;
|
|
|
import org.mockito.internal.matchers.VarargMatcher;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.net.SocketTimeoutException;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
+import java.util.concurrent.atomic.AtomicReference;
|
|
|
+import java.util.function.Function;
|
|
|
|
|
|
-import static org.mockito.Matchers.any;
|
|
|
+import static org.hamcrest.CoreMatchers.instanceOf;
|
|
|
+import static org.mockito.Matchers.anyMapOf;
|
|
|
+import static org.mockito.Matchers.anyObject;
|
|
|
+import static org.mockito.Matchers.anyString;
|
|
|
+import static org.mockito.Matchers.anyVararg;
|
|
|
import static org.mockito.Matchers.argThat;
|
|
|
import static org.mockito.Matchers.eq;
|
|
|
import static org.mockito.Mockito.mock;
|
|
@@ -38,6 +72,9 @@ import static org.mockito.Mockito.when;
|
|
|
|
|
|
public class RestHighLevelClientTests extends ESTestCase {
|
|
|
|
|
|
+ private static final ProtocolVersion HTTP_PROTOCOL = new ProtocolVersion("http", 1, 1);
|
|
|
+ private static final RequestLine REQUEST_LINE = new BasicRequestLine("GET", "/", HTTP_PROTOCOL);
|
|
|
+
|
|
|
private RestClient restClient;
|
|
|
private RestHighLevelClient restHighLevelClient;
|
|
|
|
|
@@ -47,28 +84,473 @@ public class RestHighLevelClientTests extends ESTestCase {
|
|
|
restHighLevelClient = new RestHighLevelClient(restClient);
|
|
|
}
|
|
|
|
|
|
- public void testPing() throws IOException {
|
|
|
- assertTrue(restHighLevelClient.ping());
|
|
|
- verify(restClient).performRequest(eq("HEAD"), eq("/"), argThat(new HeadersVarargMatcher()));
|
|
|
+ public void testPingSuccessful() throws IOException {
|
|
|
+ Header[] headers = RestClientTestUtil.randomHeaders(random(), "Header");
|
|
|
+ Response response = mock(Response.class);
|
|
|
+ when(response.getStatusLine()).thenReturn(newStatusLine(RestStatus.OK));
|
|
|
+ when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
|
|
|
+ anyObject(), anyVararg())).thenReturn(response);
|
|
|
+ assertTrue(restHighLevelClient.ping(headers));
|
|
|
+ verify(restClient).performRequest(eq("HEAD"), eq("/"), eq(Collections.emptyMap()),
|
|
|
+ Matchers.isNull(HttpEntity.class), argThat(new HeadersVarargMatcher(headers)));
|
|
|
}
|
|
|
|
|
|
- public void testPingFailure() throws IOException {
|
|
|
- when(restClient.performRequest(any(), any())).thenThrow(new IllegalStateException());
|
|
|
- expectThrows(IllegalStateException.class, () -> restHighLevelClient.ping());
|
|
|
+ public void testPing404NotFound() throws IOException {
|
|
|
+ Header[] headers = RestClientTestUtil.randomHeaders(random(), "Header");
|
|
|
+ Response response = mock(Response.class);
|
|
|
+ when(response.getStatusLine()).thenReturn(newStatusLine(RestStatus.NOT_FOUND));
|
|
|
+ when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
|
|
|
+ anyObject(), anyVararg())).thenReturn(response);
|
|
|
+ assertFalse(restHighLevelClient.ping(headers));
|
|
|
+ verify(restClient).performRequest(eq("HEAD"), eq("/"), eq(Collections.emptyMap()),
|
|
|
+ Matchers.isNull(HttpEntity.class), argThat(new HeadersVarargMatcher(headers)));
|
|
|
}
|
|
|
|
|
|
- public void testPingFailed() throws IOException {
|
|
|
- when(restClient.performRequest(any(), any())).thenThrow(new SocketTimeoutException());
|
|
|
- assertFalse(restHighLevelClient.ping());
|
|
|
+ public void testPingSocketTimeout() throws IOException {
|
|
|
+ Header[] headers = RestClientTestUtil.randomHeaders(random(), "Header");
|
|
|
+ when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
|
|
|
+ anyObject(), anyVararg())).thenThrow(new SocketTimeoutException());
|
|
|
+ expectThrows(SocketTimeoutException.class, () -> restHighLevelClient.ping(headers));
|
|
|
+ verify(restClient).performRequest(eq("HEAD"), eq("/"), eq(Collections.emptyMap()),
|
|
|
+ Matchers.isNull(HttpEntity.class), argThat(new HeadersVarargMatcher(headers)));
|
|
|
}
|
|
|
|
|
|
- public void testPingWithHeaders() throws IOException {
|
|
|
- Header[] headers = RestClientTestUtil.randomHeaders(random(), "Header");
|
|
|
- assertTrue(restHighLevelClient.ping(headers));
|
|
|
- verify(restClient).performRequest(eq("HEAD"), eq("/"), argThat(new HeadersVarargMatcher(headers)));
|
|
|
+ public void testRequestValidation() {
|
|
|
+ ActionRequestValidationException validationException = new ActionRequestValidationException();
|
|
|
+ validationException.addValidationError("validation error");
|
|
|
+ ActionRequest request = new ActionRequest() {
|
|
|
+ @Override
|
|
|
+ public ActionRequestValidationException validate() {
|
|
|
+ return validationException;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ {
|
|
|
+ ActionRequestValidationException actualException = expectThrows(ActionRequestValidationException.class,
|
|
|
+ () -> restHighLevelClient.performRequest(request, null, null, null));
|
|
|
+ assertSame(validationException, actualException);
|
|
|
+ }
|
|
|
+ {
|
|
|
+ TrackingActionListener trackingActionListener = new TrackingActionListener();
|
|
|
+ restHighLevelClient.performRequestAsync(request, null, null, trackingActionListener, null);
|
|
|
+ assertSame(validationException, trackingActionListener.exception.get());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testParseEntity() throws IOException {
|
|
|
+ {
|
|
|
+ IllegalStateException ise = expectThrows(IllegalStateException.class, () -> RestHighLevelClient.parseEntity(null, null));
|
|
|
+ assertEquals("Response body expected but not returned", ise.getMessage());
|
|
|
+ }
|
|
|
+ {
|
|
|
+ IllegalStateException ise = expectThrows(IllegalStateException.class,
|
|
|
+ () -> RestHighLevelClient.parseEntity(new BasicHttpEntity(), null));
|
|
|
+ assertEquals("Elasticsearch didn't return the [Content-Type] header, unable to parse response body", ise.getMessage());
|
|
|
+ }
|
|
|
+ {
|
|
|
+ StringEntity entity = new StringEntity("", ContentType.APPLICATION_SVG_XML);
|
|
|
+ IllegalStateException ise = expectThrows(IllegalStateException.class, () -> RestHighLevelClient.parseEntity(entity, null));
|
|
|
+ assertEquals("Unsupported Content-Type: " + entity.getContentType().getValue(), ise.getMessage());
|
|
|
+ }
|
|
|
+ {
|
|
|
+ CheckedFunction<XContentParser, String, IOException> entityParser = parser -> {
|
|
|
+ assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
|
+ assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken());
|
|
|
+ assertTrue(parser.nextToken().isValue());
|
|
|
+ String value = parser.text();
|
|
|
+ assertEquals(XContentParser.Token.END_OBJECT, parser.nextToken());
|
|
|
+ return value;
|
|
|
+ };
|
|
|
+ HttpEntity jsonEntity = new StringEntity("{\"field\":\"value\"}", ContentType.APPLICATION_JSON);
|
|
|
+ assertEquals("value", RestHighLevelClient.parseEntity(jsonEntity, entityParser));
|
|
|
+ HttpEntity yamlEntity = new StringEntity("---\nfield: value\n", ContentType.create("application/yaml"));
|
|
|
+ assertEquals("value", RestHighLevelClient.parseEntity(yamlEntity, entityParser));
|
|
|
+ HttpEntity smileEntity = createBinaryEntity(SmileXContent.contentBuilder(), ContentType.create("application/smile"));
|
|
|
+ assertEquals("value", RestHighLevelClient.parseEntity(smileEntity, entityParser));
|
|
|
+ HttpEntity cborEntity = createBinaryEntity(CborXContent.contentBuilder(), ContentType.create("application/cbor"));
|
|
|
+ assertEquals("value", RestHighLevelClient.parseEntity(cborEntity, entityParser));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static HttpEntity createBinaryEntity(XContentBuilder xContentBuilder, ContentType contentType) throws IOException {
|
|
|
+ try (XContentBuilder builder = xContentBuilder) {
|
|
|
+ builder.startObject();
|
|
|
+ builder.field("field", "value");
|
|
|
+ builder.endObject();
|
|
|
+ return new ByteArrayEntity(builder.bytes().toBytesRef().bytes, contentType);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testConvertExistsResponse() {
|
|
|
+ RestStatus restStatus = randomBoolean() ? RestStatus.OK : randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ boolean result = RestHighLevelClient.convertExistsResponse(response);
|
|
|
+ assertEquals(restStatus == RestStatus.OK, result);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testParseResponseException() throws IOException {
|
|
|
+ {
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(response);
|
|
|
+ ElasticsearchException elasticsearchException = RestHighLevelClient.parseResponseException(responseException);
|
|
|
+ assertEquals(responseException.getMessage(), elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getCause());
|
|
|
+ }
|
|
|
+ {
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ httpResponse.setEntity(new StringEntity("{\"error\":\"test error message\",\"status\":" + restStatus.getStatus() + "}",
|
|
|
+ ContentType.APPLICATION_JSON));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(response);
|
|
|
+ ElasticsearchException elasticsearchException = RestHighLevelClient.parseResponseException(responseException);
|
|
|
+ assertEquals("Elasticsearch exception [type=exception, reason=test error message]", elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getSuppressed()[0]);
|
|
|
+ }
|
|
|
+ {
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ httpResponse.setEntity(new StringEntity("{\"error\":", ContentType.APPLICATION_JSON));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(response);
|
|
|
+ ElasticsearchException elasticsearchException = RestHighLevelClient.parseResponseException(responseException);
|
|
|
+ assertEquals("Unable to parse response body", elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getCause());
|
|
|
+ assertThat(elasticsearchException.getSuppressed()[0], instanceOf(IOException.class));
|
|
|
+ }
|
|
|
+ {
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ httpResponse.setEntity(new StringEntity("{\"status\":" + restStatus.getStatus() + "}", ContentType.APPLICATION_JSON));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(response);
|
|
|
+ ElasticsearchException elasticsearchException = RestHighLevelClient.parseResponseException(responseException);
|
|
|
+ assertEquals("Unable to parse response body", elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getCause());
|
|
|
+ assertThat(elasticsearchException.getSuppressed()[0], instanceOf(IllegalStateException.class));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testPerformRequestOnSuccess() throws IOException {
|
|
|
+ MainRequest mainRequest = new MainRequest();
|
|
|
+ Function<MainRequest, Request> requestConverter = request -> new Request("GET", "/", Collections.emptyMap(), null);
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ Response mockResponse = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
|
|
|
+ anyObject(), anyVararg())).thenReturn(mockResponse);
|
|
|
+ {
|
|
|
+ Integer result = restHighLevelClient.performRequest(mainRequest, requestConverter,
|
|
|
+ response -> response.getStatusLine().getStatusCode(), Collections.emptySet());
|
|
|
+ assertEquals(restStatus.getStatus(), result.intValue());
|
|
|
+ }
|
|
|
+ {
|
|
|
+ IOException ioe = expectThrows(IOException.class, () -> restHighLevelClient.performRequest(mainRequest,
|
|
|
+ requestConverter, response -> {throw new IllegalStateException();}, Collections.emptySet()));
|
|
|
+ assertEquals("Unable to parse response body for Response{requestLine=GET / http/1.1, host=http://localhost:9200, " +
|
|
|
+ "response=http/1.1 " + restStatus.getStatus() + " " + restStatus.name() + "}", ioe.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testPerformRequestOnResponseExceptionWithoutEntity() throws IOException {
|
|
|
+ MainRequest mainRequest = new MainRequest();
|
|
|
+ Function<MainRequest, Request> requestConverter = request -> new Request("GET", "/", Collections.emptyMap(), null);
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ Response mockResponse = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(mockResponse);
|
|
|
+ when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
|
|
|
+ anyObject(), anyVararg())).thenThrow(responseException);
|
|
|
+ ElasticsearchException elasticsearchException = expectThrows(ElasticsearchException.class,
|
|
|
+ () -> restHighLevelClient.performRequest(mainRequest, requestConverter,
|
|
|
+ response -> response.getStatusLine().getStatusCode(), Collections.emptySet()));
|
|
|
+ assertEquals(responseException.getMessage(), elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getCause());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testPerformRequestOnResponseExceptionWithEntity() throws IOException {
|
|
|
+ MainRequest mainRequest = new MainRequest();
|
|
|
+ Function<MainRequest, Request> requestConverter = request -> new Request("GET", "/", Collections.emptyMap(), null);
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ httpResponse.setEntity(new StringEntity("{\"error\":\"test error message\",\"status\":" + restStatus.getStatus() + "}",
|
|
|
+ ContentType.APPLICATION_JSON));
|
|
|
+ Response mockResponse = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(mockResponse);
|
|
|
+ when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
|
|
|
+ anyObject(), anyVararg())).thenThrow(responseException);
|
|
|
+ ElasticsearchException elasticsearchException = expectThrows(ElasticsearchException.class,
|
|
|
+ () -> restHighLevelClient.performRequest(mainRequest, requestConverter,
|
|
|
+ response -> response.getStatusLine().getStatusCode(), Collections.emptySet()));
|
|
|
+ assertEquals("Elasticsearch exception [type=exception, reason=test error message]", elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getSuppressed()[0]);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testPerformRequestOnResponseExceptionWithBrokenEntity() throws IOException {
|
|
|
+ MainRequest mainRequest = new MainRequest();
|
|
|
+ Function<MainRequest, Request> requestConverter = request -> new Request("GET", "/", Collections.emptyMap(), null);
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ httpResponse.setEntity(new StringEntity("{\"error\":", ContentType.APPLICATION_JSON));
|
|
|
+ Response mockResponse = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(mockResponse);
|
|
|
+ when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
|
|
|
+ anyObject(), anyVararg())).thenThrow(responseException);
|
|
|
+ ElasticsearchException elasticsearchException = expectThrows(ElasticsearchException.class,
|
|
|
+ () -> restHighLevelClient.performRequest(mainRequest, requestConverter,
|
|
|
+ response -> response.getStatusLine().getStatusCode(), Collections.emptySet()));
|
|
|
+ assertEquals("Unable to parse response body", elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getCause());
|
|
|
+ assertThat(elasticsearchException.getSuppressed()[0], instanceOf(JsonParseException.class));
|
|
|
}
|
|
|
|
|
|
- private class HeadersVarargMatcher extends ArgumentMatcher<Header[]> implements VarargMatcher {
|
|
|
+ public void testPerformRequestOnResponseExceptionWithBrokenEntity2() throws IOException {
|
|
|
+ MainRequest mainRequest = new MainRequest();
|
|
|
+ Function<MainRequest, Request> requestConverter = request -> new Request("GET", "/", Collections.emptyMap(), null);
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ httpResponse.setEntity(new StringEntity("{\"status\":" + restStatus.getStatus() + "}", ContentType.APPLICATION_JSON));
|
|
|
+ Response mockResponse = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(mockResponse);
|
|
|
+ when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
|
|
|
+ anyObject(), anyVararg())).thenThrow(responseException);
|
|
|
+ ElasticsearchException elasticsearchException = expectThrows(ElasticsearchException.class,
|
|
|
+ () -> restHighLevelClient.performRequest(mainRequest, requestConverter,
|
|
|
+ response -> response.getStatusLine().getStatusCode(), Collections.emptySet()));
|
|
|
+ assertEquals("Unable to parse response body", elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getCause());
|
|
|
+ assertThat(elasticsearchException.getSuppressed()[0], instanceOf(IllegalStateException.class));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testPerformRequestOnResponseExceptionWithIgnores() throws IOException {
|
|
|
+ MainRequest mainRequest = new MainRequest();
|
|
|
+ Function<MainRequest, Request> requestConverter = request -> new Request("GET", "/", Collections.emptyMap(), null);
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(RestStatus.NOT_FOUND));
|
|
|
+ Response mockResponse = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(mockResponse);
|
|
|
+ when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
|
|
|
+ anyObject(), anyVararg())).thenThrow(responseException);
|
|
|
+ //although we got an exception, we turn it into a successful response because the status code was provided among ignores
|
|
|
+ assertEquals(Integer.valueOf(404), restHighLevelClient.performRequest(mainRequest, requestConverter,
|
|
|
+ response -> response.getStatusLine().getStatusCode(), Collections.singleton(404)));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testPerformRequestOnResponseExceptionWithIgnoresErrorNoBody() throws IOException {
|
|
|
+ MainRequest mainRequest = new MainRequest();
|
|
|
+ Function<MainRequest, Request> requestConverter = request -> new Request("GET", "/", Collections.emptyMap(), null);
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(RestStatus.NOT_FOUND));
|
|
|
+ Response mockResponse = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(mockResponse);
|
|
|
+ when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
|
|
|
+ anyObject(), anyVararg())).thenThrow(responseException);
|
|
|
+ ElasticsearchException elasticsearchException = expectThrows(ElasticsearchException.class,
|
|
|
+ () -> restHighLevelClient.performRequest(mainRequest, requestConverter,
|
|
|
+ response -> {throw new IllegalStateException();}, Collections.singleton(404)));
|
|
|
+ assertEquals(RestStatus.NOT_FOUND, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getCause());
|
|
|
+ assertEquals(responseException.getMessage(), elasticsearchException.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testPerformRequestOnResponseExceptionWithIgnoresErrorValidBody() throws IOException {
|
|
|
+ MainRequest mainRequest = new MainRequest();
|
|
|
+ Function<MainRequest, Request> requestConverter = request -> new Request("GET", "/", Collections.emptyMap(), null);
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(RestStatus.NOT_FOUND));
|
|
|
+ httpResponse.setEntity(new StringEntity("{\"error\":\"test error message\",\"status\":404}",
|
|
|
+ ContentType.APPLICATION_JSON));
|
|
|
+ Response mockResponse = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(mockResponse);
|
|
|
+ when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
|
|
|
+ anyObject(), anyVararg())).thenThrow(responseException);
|
|
|
+ ElasticsearchException elasticsearchException = expectThrows(ElasticsearchException.class,
|
|
|
+ () -> restHighLevelClient.performRequest(mainRequest, requestConverter,
|
|
|
+ response -> {throw new IllegalStateException();}, Collections.singleton(404)));
|
|
|
+ assertEquals(RestStatus.NOT_FOUND, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getSuppressed()[0]);
|
|
|
+ assertEquals("Elasticsearch exception [type=exception, reason=test error message]", elasticsearchException.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testWrapResponseListenerOnSuccess() throws IOException {
|
|
|
+ {
|
|
|
+ TrackingActionListener trackingActionListener = new TrackingActionListener();
|
|
|
+ ResponseListener responseListener = RestHighLevelClient.wrapResponseListener(
|
|
|
+ response -> response.getStatusLine().getStatusCode(), trackingActionListener, Collections.emptySet());
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ responseListener.onSuccess(new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse));
|
|
|
+ assertNull(trackingActionListener.exception.get());
|
|
|
+ assertEquals(restStatus.getStatus(), trackingActionListener.statusCode.get());
|
|
|
+ }
|
|
|
+ {
|
|
|
+ TrackingActionListener trackingActionListener = new TrackingActionListener();
|
|
|
+ ResponseListener responseListener = RestHighLevelClient.wrapResponseListener(
|
|
|
+ response -> {throw new IllegalStateException();}, trackingActionListener, Collections.emptySet());
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ responseListener.onSuccess(new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse));
|
|
|
+ assertThat(trackingActionListener.exception.get(), instanceOf(IOException.class));
|
|
|
+ IOException ioe = (IOException) trackingActionListener.exception.get();
|
|
|
+ assertEquals("Unable to parse response body for Response{requestLine=GET / http/1.1, host=http://localhost:9200, " +
|
|
|
+ "response=http/1.1 " + restStatus.getStatus() + " " + restStatus.name() + "}", ioe.getMessage());
|
|
|
+ assertThat(ioe.getCause(), instanceOf(IllegalStateException.class));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testWrapResponseListenerOnException() throws IOException {
|
|
|
+ TrackingActionListener trackingActionListener = new TrackingActionListener();
|
|
|
+ ResponseListener responseListener = RestHighLevelClient.wrapResponseListener(
|
|
|
+ response -> response.getStatusLine().getStatusCode(), trackingActionListener, Collections.emptySet());
|
|
|
+ IllegalStateException exception = new IllegalStateException();
|
|
|
+ responseListener.onFailure(exception);
|
|
|
+ assertSame(exception, trackingActionListener.exception.get());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testWrapResponseListenerOnResponseExceptionWithoutEntity() throws IOException {
|
|
|
+ TrackingActionListener trackingActionListener = new TrackingActionListener();
|
|
|
+ ResponseListener responseListener = RestHighLevelClient.wrapResponseListener(
|
|
|
+ response -> response.getStatusLine().getStatusCode(), trackingActionListener, Collections.emptySet());
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(response);
|
|
|
+ responseListener.onFailure(responseException);
|
|
|
+ assertThat(trackingActionListener.exception.get(), instanceOf(ElasticsearchException.class));
|
|
|
+ ElasticsearchException elasticsearchException = (ElasticsearchException) trackingActionListener.exception.get();
|
|
|
+ assertEquals(responseException.getMessage(), elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getCause());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testWrapResponseListenerOnResponseExceptionWithEntity() throws IOException {
|
|
|
+ TrackingActionListener trackingActionListener = new TrackingActionListener();
|
|
|
+ ResponseListener responseListener = RestHighLevelClient.wrapResponseListener(
|
|
|
+ response -> response.getStatusLine().getStatusCode(), trackingActionListener, Collections.emptySet());
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ httpResponse.setEntity(new StringEntity("{\"error\":\"test error message\",\"status\":" + restStatus.getStatus() + "}",
|
|
|
+ ContentType.APPLICATION_JSON));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(response);
|
|
|
+ responseListener.onFailure(responseException);
|
|
|
+ assertThat(trackingActionListener.exception.get(), instanceOf(ElasticsearchException.class));
|
|
|
+ ElasticsearchException elasticsearchException = (ElasticsearchException)trackingActionListener.exception.get();
|
|
|
+ assertEquals("Elasticsearch exception [type=exception, reason=test error message]", elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getSuppressed()[0]);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testWrapResponseListenerOnResponseExceptionWithBrokenEntity() throws IOException {
|
|
|
+ {
|
|
|
+ TrackingActionListener trackingActionListener = new TrackingActionListener();
|
|
|
+ ResponseListener responseListener = RestHighLevelClient.wrapResponseListener(
|
|
|
+ response -> response.getStatusLine().getStatusCode(), trackingActionListener, Collections.emptySet());
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ httpResponse.setEntity(new StringEntity("{\"error\":", ContentType.APPLICATION_JSON));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(response);
|
|
|
+ responseListener.onFailure(responseException);
|
|
|
+ assertThat(trackingActionListener.exception.get(), instanceOf(ElasticsearchException.class));
|
|
|
+ ElasticsearchException elasticsearchException = (ElasticsearchException)trackingActionListener.exception.get();
|
|
|
+ assertEquals("Unable to parse response body", elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getCause());
|
|
|
+ assertThat(elasticsearchException.getSuppressed()[0], instanceOf(JsonParseException.class));
|
|
|
+ }
|
|
|
+ {
|
|
|
+ TrackingActionListener trackingActionListener = new TrackingActionListener();
|
|
|
+ ResponseListener responseListener = RestHighLevelClient.wrapResponseListener(
|
|
|
+ response -> response.getStatusLine().getStatusCode(), trackingActionListener, Collections.emptySet());
|
|
|
+ RestStatus restStatus = randomFrom(RestStatus.values());
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(restStatus));
|
|
|
+ httpResponse.setEntity(new StringEntity("{\"status\":" + restStatus.getStatus() + "}", ContentType.APPLICATION_JSON));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(response);
|
|
|
+ responseListener.onFailure(responseException);
|
|
|
+ assertThat(trackingActionListener.exception.get(), instanceOf(ElasticsearchException.class));
|
|
|
+ ElasticsearchException elasticsearchException = (ElasticsearchException)trackingActionListener.exception.get();
|
|
|
+ assertEquals("Unable to parse response body", elasticsearchException.getMessage());
|
|
|
+ assertEquals(restStatus, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getCause());
|
|
|
+ assertThat(elasticsearchException.getSuppressed()[0], instanceOf(IllegalStateException.class));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testWrapResponseListenerOnResponseExceptionWithIgnores() throws IOException {
|
|
|
+ TrackingActionListener trackingActionListener = new TrackingActionListener();
|
|
|
+ ResponseListener responseListener = RestHighLevelClient.wrapResponseListener(
|
|
|
+ response -> response.getStatusLine().getStatusCode(), trackingActionListener, Collections.singleton(404));
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(RestStatus.NOT_FOUND));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(response);
|
|
|
+ responseListener.onFailure(responseException);
|
|
|
+ //although we got an exception, we turn it into a successful response because the status code was provided among ignores
|
|
|
+ assertNull(trackingActionListener.exception.get());
|
|
|
+ assertEquals(404, trackingActionListener.statusCode.get());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testWrapResponseListenerOnResponseExceptionWithIgnoresErrorNoBody() throws IOException {
|
|
|
+ TrackingActionListener trackingActionListener = new TrackingActionListener();
|
|
|
+ //response parsing throws exception while handling ignores. same as when GetResponse#fromXContent throws error when trying
|
|
|
+ //to parse a 404 response which contains an error rather than a valid document not found response.
|
|
|
+ ResponseListener responseListener = RestHighLevelClient.wrapResponseListener(
|
|
|
+ response -> { throw new IllegalStateException(); }, trackingActionListener, Collections.singleton(404));
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(RestStatus.NOT_FOUND));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(response);
|
|
|
+ responseListener.onFailure(responseException);
|
|
|
+ assertThat(trackingActionListener.exception.get(), instanceOf(ElasticsearchException.class));
|
|
|
+ ElasticsearchException elasticsearchException = (ElasticsearchException)trackingActionListener.exception.get();
|
|
|
+ assertEquals(RestStatus.NOT_FOUND, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getCause());
|
|
|
+ assertEquals(responseException.getMessage(), elasticsearchException.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testWrapResponseListenerOnResponseExceptionWithIgnoresErrorValidBody() throws IOException {
|
|
|
+ TrackingActionListener trackingActionListener = new TrackingActionListener();
|
|
|
+ //response parsing throws exception while handling ignores. same as when GetResponse#fromXContent throws error when trying
|
|
|
+ //to parse a 404 response which contains an error rather than a valid document not found response.
|
|
|
+ ResponseListener responseListener = RestHighLevelClient.wrapResponseListener(
|
|
|
+ response -> { throw new IllegalStateException(); }, trackingActionListener, Collections.singleton(404));
|
|
|
+ HttpResponse httpResponse = new BasicHttpResponse(newStatusLine(RestStatus.NOT_FOUND));
|
|
|
+ httpResponse.setEntity(new StringEntity("{\"error\":\"test error message\",\"status\":404}",
|
|
|
+ ContentType.APPLICATION_JSON));
|
|
|
+ Response response = new Response(REQUEST_LINE, new HttpHost("localhost", 9200), httpResponse);
|
|
|
+ ResponseException responseException = new ResponseException(response);
|
|
|
+ responseListener.onFailure(responseException);
|
|
|
+ assertThat(trackingActionListener.exception.get(), instanceOf(ElasticsearchException.class));
|
|
|
+ ElasticsearchException elasticsearchException = (ElasticsearchException)trackingActionListener.exception.get();
|
|
|
+ assertEquals(RestStatus.NOT_FOUND, elasticsearchException.status());
|
|
|
+ assertSame(responseException, elasticsearchException.getSuppressed()[0]);
|
|
|
+ assertEquals("Elasticsearch exception [type=exception, reason=test error message]", elasticsearchException.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ private static class TrackingActionListener implements ActionListener<Integer> {
|
|
|
+ private final AtomicInteger statusCode = new AtomicInteger(-1);
|
|
|
+ private final AtomicReference<Exception> exception = new AtomicReference<>();
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onResponse(Integer statusCode) {
|
|
|
+ assertTrue(this.statusCode.compareAndSet(-1, statusCode));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onFailure(Exception e) {
|
|
|
+ assertTrue(exception.compareAndSet(null, e));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static class HeadersVarargMatcher extends ArgumentMatcher<Header[]> implements VarargMatcher {
|
|
|
private Header[] expectedHeaders;
|
|
|
|
|
|
HeadersVarargMatcher(Header... expectedHeaders) {
|
|
@@ -84,4 +566,8 @@ public class RestHighLevelClientTests extends ESTestCase {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ private static StatusLine newStatusLine(RestStatus restStatus) {
|
|
|
+ return new BasicStatusLine(HTTP_PROTOCOL, restStatus.getStatus(), restStatus.name());
|
|
|
+ }
|
|
|
}
|