소스 검색

LLClient: Add setJsonEntity (#30447)

Adds `Request#setJsonEntity(String)` which short circuits the process of
sending a json string which is super common.
Nik Everett 7 년 전
부모
커밋
b4502dbf74

+ 13 - 0
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 final class Request {
         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.

+ 20 - 1
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.HttpEntity;
 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 class RequestTests extends RestClientTestCase {
         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);

+ 4 - 1
client/rest/src/test/java/org/elasticsearch/client/documentation/RestClientDocumentation.java

@@ -168,10 +168,13 @@ public class RestClientDocumentation {
             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"),

+ 1 - 0
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])
 

+ 8 - 0
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"]

+ 6 - 9
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 @@ final class RemoteRequestBuilders {
             }
 
             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 @@ final class RemoteRequestBuilders {
 
         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 @@ final class RemoteRequestBuilders {
             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 @@ final class RemoteRequestBuilders {
 
         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);
         }