diff --git a/client/rest/src/main/java/org/elasticsearch/client/Request.java b/client/rest/src/main/java/org/elasticsearch/client/Request.java index bf0012339fb41..92610239cae92 100644 --- a/client/rest/src/main/java/org/elasticsearch/client/Request.java +++ b/client/rest/src/main/java/org/elasticsearch/client/Request.java @@ -19,8 +19,10 @@ package org.elasticsearch.client; +import org.apache.http.entity.ContentType; import org.apache.http.Header; import org.apache.http.HttpEntity; +import org.apache.http.nio.entity.NStringEntity; import org.apache.http.nio.protocol.HttpAsyncResponseConsumer; import java.util.Arrays; @@ -103,6 +105,17 @@ public void setEntity(HttpEntity entity) { this.entity = entity; } + /** + * Set the body of the request to a string. If not set or set to + * {@code null} then no body is sent with the request. The + * {@code Content-Type} will be sent as {@code application/json}. + * If you need a different content type then use + * {@link #setEntity(HttpEntity)}. + */ + public void setJsonEntity(String entity) { + setEntity(entity == null ? null : new NStringEntity(entity, ContentType.APPLICATION_JSON)); + } + /** * The body of the request. If {@code null} then no body * is sent with the request. diff --git a/client/rest/src/test/java/org/elasticsearch/client/RequestTests.java b/client/rest/src/test/java/org/elasticsearch/client/RequestTests.java index 98fcf8421ae6a..b83115a5341dd 100644 --- a/client/rest/src/test/java/org/elasticsearch/client/RequestTests.java +++ b/client/rest/src/test/java/org/elasticsearch/client/RequestTests.java @@ -19,6 +19,8 @@ package org.elasticsearch.client; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -27,9 +29,11 @@ import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.message.BasicHeader; +import org.apache.http.nio.entity.NStringEntity; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; public class RequestTests extends RestClientTestCase { @@ -99,12 +103,27 @@ public void testSetEntity() { final String endpoint = randomAsciiLettersOfLengthBetween(1, 10); final HttpEntity entity = randomBoolean() ? new StringEntity(randomAsciiLettersOfLengthBetween(1, 100), ContentType.TEXT_PLAIN) : null; - Request request = new Request(method, endpoint); + Request request = new Request(method, endpoint); request.setEntity(entity); assertEquals(entity, request.getEntity()); } + public void testSetJsonEntity() throws IOException { + final String method = randomFrom(new String[] {"GET", "PUT", "POST", "HEAD", "DELETE"}); + final String endpoint = randomAsciiLettersOfLengthBetween(1, 10); + + Request request = new Request(method, endpoint); + assertNull(request.getEntity()); + + final String json = randomAsciiLettersOfLengthBetween(1, 100); + request.setJsonEntity(json); + assertEquals(ContentType.APPLICATION_JSON.toString(), request.getEntity().getContentType().getValue()); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + request.getEntity().writeTo(os); + assertEquals(json, new String(os.toByteArray(), ContentType.APPLICATION_JSON.getCharset())); + } + public void testSetHeaders() { final String method = randomFrom(new String[] {"GET", "PUT", "POST", "HEAD", "DELETE"}); final String endpoint = randomAsciiLettersOfLengthBetween(1, 10); diff --git a/client/rest/src/test/java/org/elasticsearch/client/documentation/RestClientDocumentation.java b/client/rest/src/test/java/org/elasticsearch/client/documentation/RestClientDocumentation.java index aa89a7d76ab26..5ee97399b34e6 100644 --- a/client/rest/src/test/java/org/elasticsearch/client/documentation/RestClientDocumentation.java +++ b/client/rest/src/test/java/org/elasticsearch/client/documentation/RestClientDocumentation.java @@ -168,10 +168,13 @@ public void onFailure(Exception exception) { request.addParameter("pretty", "true"); //end::rest-client-parameters //tag::rest-client-body - request.setEntity(new StringEntity( + request.setEntity(new NStringEntity( "{\"json\":\"text\"}", ContentType.APPLICATION_JSON)); //end::rest-client-body + //tag::rest-client-body-shorter + request.setJsonEntity("{\"json\":\"text\"}"); + //end::rest-client-body-shorter //tag::rest-client-headers request.setHeaders( new BasicHeader("Accept", "text/plain"), diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 2b4c316e7cb37..5f7ed63cdd8ad 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -165,6 +165,7 @@ analysis module. ({pull}30397[#30397]) Added new "Request" object flavored request methods in the RestClient. Prefer these instead of the multi-argument versions. ({pull}29623[#29623]) +Added `setJsonEntity` to `Request` object so it is marginally easier to send JSON. ({pull}30447[#30447]) Watcher HTTP client used in watches now allows more parallel connections to the same endpoint and evicts long running connections. ({pull}30130[#30130]) diff --git a/docs/java-rest/low-level/usage.asciidoc b/docs/java-rest/low-level/usage.asciidoc index 5ffc4332a7681..68367b9a64fdf 100644 --- a/docs/java-rest/low-level/usage.asciidoc +++ b/docs/java-rest/low-level/usage.asciidoc @@ -263,6 +263,14 @@ IMPORTANT: The `ContentType` specified for the `HttpEntity` is important because it will be used to set the `Content-Type` header so that Elasticsearch can properly parse the content. +You can also set it to a `String` which will default to +a `ContentType` of `application/json`. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-body-shorter] +-------------------------------------------------- + And you can set a list of headers to send with the request: ["source","java",subs="attributes,callouts,macros"] diff --git a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuilders.java b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuilders.java index 4dcc0a34758d6..e8e3760882eea 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuilders.java +++ b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuilders.java @@ -19,10 +19,8 @@ package org.elasticsearch.index.reindex.remote; -import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.lucene.util.BytesRef; +import org.apache.http.nio.entity.NStringEntity; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.Version; import org.elasticsearch.action.search.SearchRequest; @@ -151,8 +149,7 @@ static Request initialSearch(SearchRequest searchRequest, BytesReference query, } entity.endObject(); - BytesRef bytes = BytesReference.bytes(entity).toBytesRef(); - request.setEntity(new ByteArrayEntity(bytes.bytes, bytes.offset, bytes.length, ContentType.APPLICATION_JSON)); + request.setJsonEntity(Strings.toString(entity)); } catch (IOException e) { throw new ElasticsearchException("unexpected error building entity", e); } @@ -199,7 +196,7 @@ static Request scroll(String scroll, TimeValue keepAlive, Version remoteVersion) if (remoteVersion.before(Version.fromId(2000099))) { // Versions before 2.0.0 extract the plain scroll_id from the body - request.setEntity(new StringEntity(scroll, ContentType.TEXT_PLAIN)); + request.setEntity(new NStringEntity(scroll, ContentType.TEXT_PLAIN)); return request; } @@ -207,7 +204,7 @@ static Request scroll(String scroll, TimeValue keepAlive, Version remoteVersion) entity.startObject() .field("scroll_id", scroll) .endObject(); - request.setEntity(new StringEntity(Strings.toString(entity), ContentType.APPLICATION_JSON)); + request.setJsonEntity(Strings.toString(entity)); } catch (IOException e) { throw new ElasticsearchException("failed to build scroll entity", e); } @@ -219,14 +216,14 @@ static Request clearScroll(String scroll, Version remoteVersion) { if (remoteVersion.before(Version.fromId(2000099))) { // Versions before 2.0.0 extract the plain scroll_id from the body - request.setEntity(new StringEntity(scroll, ContentType.TEXT_PLAIN)); + request.setEntity(new NStringEntity(scroll, ContentType.TEXT_PLAIN)); return request; } try (XContentBuilder entity = JsonXContent.contentBuilder()) { entity.startObject() .array("scroll_id", scroll) .endObject(); - request.setEntity(new StringEntity(Strings.toString(entity), ContentType.APPLICATION_JSON)); + request.setJsonEntity(Strings.toString(entity)); } catch (IOException e) { throw new ElasticsearchException("failed to build clear scroll entity", e); }