/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
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.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.Build;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.main.MainRequest;
import org.elasticsearch.action.main.MainResponse;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
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.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import static org.elasticsearch.common.xcontent.XContentHelper.toXContent;
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;
import static org.mockito.Mockito.verify;
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;
@Before
public void initClient() {
restClient = mock(RestClient.class);
restHighLevelClient = new RestHighLevelClient(restClient);
}
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 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 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 testInfo() throws IOException {
Header[] headers = RestClientTestUtil.randomHeaders(random(), "Header");
Response response = mock(Response.class);
MainResponse testInfo = new MainResponse("nodeName", Version.CURRENT, new ClusterName("clusterName"), "clusterUuid",
Build.CURRENT, true);
when(response.getEntity()).thenReturn(
new StringEntity(toXContent(testInfo, XContentType.JSON, false).utf8ToString(), ContentType.APPLICATION_JSON));
when(restClient.performRequest(anyString(), anyString(), anyMapOf(String.class, String.class),
anyObject(), anyVararg())).thenReturn(response);
MainResponse receivedInfo = restHighLevelClient.info(headers);
assertEquals(testInfo, receivedInfo);
verify(restClient).performRequest(eq("GET"), eq("/"), eq(Collections.emptyMap()),
Matchers.isNull(HttpEntity.class), 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 StringEntity("", (ContentType) null), 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();
CheckedFunction<MainRequest, Request, IOException> 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();
CheckedFunction<MainRequest, Request, IOException> 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();
CheckedFunction<MainRequest, Request, IOException> 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();
CheckedFunction<MainRequest, Request, IOException> 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));
}
public void testPerformRequestOnResponseExceptionWithBrokenEntity2() throws IOException {
MainRequest mainRequest = new MainRequest();
CheckedFunction<MainRequest, Request, IOException> 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();
CheckedFunction<MainRequest, Request, IOException> 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();
CheckedFunction<MainRequest, Request, IOException> 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();
CheckedFunction<MainRequest, Request, IOException> 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() {
{
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() {
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());
}
public void testNamedXContents() {
List<NamedXContentRegistry.Entry> namedXContents = RestHighLevelClient.getNamedXContents();
assertEquals(0, namedXContents.size());
}
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) {
this.expectedHeaders = expectedHeaders;
}
@Override
public boolean matches(Object varargArgument) {
if (varargArgument instanceof Header[]) {
Header[] actualHeaders = (Header[]) varargArgument;
return new ArrayEquals(expectedHeaders).matches(actualHeaders);
}
return false;
}
}
private static StatusLine newStatusLine(RestStatus restStatus) {
return new BasicStatusLine(HTTP_PROTOCOL, restStatus.getStatus(), restStatus.name());
}
}