Skip to content

Commit b4502db

Browse files
authored
LLClient: Add setJsonEntity (#30447)
Adds `Request#setJsonEntity(String)` which short circuits the process of sending a json string which is super common.
1 parent 9828e11 commit b4502db

File tree

6 files changed

+52
-11
lines changed

6 files changed

+52
-11
lines changed

client/rest/src/main/java/org/elasticsearch/client/Request.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919

2020
package org.elasticsearch.client;
2121

22+
import org.apache.http.entity.ContentType;
2223
import org.apache.http.Header;
2324
import org.apache.http.HttpEntity;
25+
import org.apache.http.nio.entity.NStringEntity;
2426
import org.apache.http.nio.protocol.HttpAsyncResponseConsumer;
2527

2628
import java.util.Arrays;
@@ -103,6 +105,17 @@ public void setEntity(HttpEntity entity) {
103105
this.entity = entity;
104106
}
105107

108+
/**
109+
* Set the body of the request to a string. If not set or set to
110+
* {@code null} then no body is sent with the request. The
111+
* {@code Content-Type} will be sent as {@code application/json}.
112+
* If you need a different content type then use
113+
* {@link #setEntity(HttpEntity)}.
114+
*/
115+
public void setJsonEntity(String entity) {
116+
setEntity(entity == null ? null : new NStringEntity(entity, ContentType.APPLICATION_JSON));
117+
}
118+
106119
/**
107120
* The body of the request. If {@code null} then no body
108121
* is sent with the request.

client/rest/src/test/java/org/elasticsearch/client/RequestTests.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
package org.elasticsearch.client;
2121

22+
import java.io.ByteArrayOutputStream;
23+
import java.io.IOException;
2224
import java.util.HashMap;
2325
import java.util.Map;
2426

@@ -27,9 +29,11 @@
2729
import org.apache.http.entity.ContentType;
2830
import org.apache.http.entity.StringEntity;
2931
import org.apache.http.message.BasicHeader;
32+
import org.apache.http.nio.entity.NStringEntity;
3033

3134
import static org.junit.Assert.assertArrayEquals;
3235
import static org.junit.Assert.assertEquals;
36+
import static org.junit.Assert.assertNull;
3337
import static org.junit.Assert.fail;
3438

3539
public class RequestTests extends RestClientTestCase {
@@ -99,12 +103,27 @@ public void testSetEntity() {
99103
final String endpoint = randomAsciiLettersOfLengthBetween(1, 10);
100104
final HttpEntity entity =
101105
randomBoolean() ? new StringEntity(randomAsciiLettersOfLengthBetween(1, 100), ContentType.TEXT_PLAIN) : null;
102-
Request request = new Request(method, endpoint);
103106

107+
Request request = new Request(method, endpoint);
104108
request.setEntity(entity);
105109
assertEquals(entity, request.getEntity());
106110
}
107111

112+
public void testSetJsonEntity() throws IOException {
113+
final String method = randomFrom(new String[] {"GET", "PUT", "POST", "HEAD", "DELETE"});
114+
final String endpoint = randomAsciiLettersOfLengthBetween(1, 10);
115+
116+
Request request = new Request(method, endpoint);
117+
assertNull(request.getEntity());
118+
119+
final String json = randomAsciiLettersOfLengthBetween(1, 100);
120+
request.setJsonEntity(json);
121+
assertEquals(ContentType.APPLICATION_JSON.toString(), request.getEntity().getContentType().getValue());
122+
ByteArrayOutputStream os = new ByteArrayOutputStream();
123+
request.getEntity().writeTo(os);
124+
assertEquals(json, new String(os.toByteArray(), ContentType.APPLICATION_JSON.getCharset()));
125+
}
126+
108127
public void testSetHeaders() {
109128
final String method = randomFrom(new String[] {"GET", "PUT", "POST", "HEAD", "DELETE"});
110129
final String endpoint = randomAsciiLettersOfLengthBetween(1, 10);

client/rest/src/test/java/org/elasticsearch/client/documentation/RestClientDocumentation.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,13 @@ public void onFailure(Exception exception) {
168168
request.addParameter("pretty", "true");
169169
//end::rest-client-parameters
170170
//tag::rest-client-body
171-
request.setEntity(new StringEntity(
171+
request.setEntity(new NStringEntity(
172172
"{\"json\":\"text\"}",
173173
ContentType.APPLICATION_JSON));
174174
//end::rest-client-body
175+
//tag::rest-client-body-shorter
176+
request.setJsonEntity("{\"json\":\"text\"}");
177+
//end::rest-client-body-shorter
175178
//tag::rest-client-headers
176179
request.setHeaders(
177180
new BasicHeader("Accept", "text/plain"),

docs/CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ analysis module. ({pull}30397[#30397])
165165
Added new "Request" object flavored request methods in the RestClient. Prefer
166166
these instead of the multi-argument versions. ({pull}29623[#29623])
167167

168+
Added `setJsonEntity` to `Request` object so it is marginally easier to send JSON. ({pull}30447[#30447])
168169
Watcher HTTP client used in watches now allows more parallel connections to the
169170
same endpoint and evicts long running connections. ({pull}30130[#30130])
170171

docs/java-rest/low-level/usage.asciidoc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@ IMPORTANT: The `ContentType` specified for the `HttpEntity` is important
263263
because it will be used to set the `Content-Type` header so that Elasticsearch
264264
can properly parse the content.
265265

266+
You can also set it to a `String` which will default to
267+
a `ContentType` of `application/json`.
268+
269+
["source","java",subs="attributes,callouts,macros"]
270+
--------------------------------------------------
271+
include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-body-shorter]
272+
--------------------------------------------------
273+
266274
And you can set a list of headers to send with the request:
267275

268276
["source","java",subs="attributes,callouts,macros"]

modules/reindex/src/main/java/org/elasticsearch/index/reindex/remote/RemoteRequestBuilders.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@
1919

2020
package org.elasticsearch.index.reindex.remote;
2121

22-
import org.apache.http.entity.ByteArrayEntity;
2322
import org.apache.http.entity.ContentType;
24-
import org.apache.http.entity.StringEntity;
25-
import org.apache.lucene.util.BytesRef;
23+
import org.apache.http.nio.entity.NStringEntity;
2624
import org.elasticsearch.ElasticsearchException;
2725
import org.elasticsearch.Version;
2826
import org.elasticsearch.action.search.SearchRequest;
@@ -151,8 +149,7 @@ static Request initialSearch(SearchRequest searchRequest, BytesReference query,
151149
}
152150

153151
entity.endObject();
154-
BytesRef bytes = BytesReference.bytes(entity).toBytesRef();
155-
request.setEntity(new ByteArrayEntity(bytes.bytes, bytes.offset, bytes.length, ContentType.APPLICATION_JSON));
152+
request.setJsonEntity(Strings.toString(entity));
156153
} catch (IOException e) {
157154
throw new ElasticsearchException("unexpected error building entity", e);
158155
}
@@ -199,15 +196,15 @@ static Request scroll(String scroll, TimeValue keepAlive, Version remoteVersion)
199196

200197
if (remoteVersion.before(Version.fromId(2000099))) {
201198
// Versions before 2.0.0 extract the plain scroll_id from the body
202-
request.setEntity(new StringEntity(scroll, ContentType.TEXT_PLAIN));
199+
request.setEntity(new NStringEntity(scroll, ContentType.TEXT_PLAIN));
203200
return request;
204201
}
205202

206203
try (XContentBuilder entity = JsonXContent.contentBuilder()) {
207204
entity.startObject()
208205
.field("scroll_id", scroll)
209206
.endObject();
210-
request.setEntity(new StringEntity(Strings.toString(entity), ContentType.APPLICATION_JSON));
207+
request.setJsonEntity(Strings.toString(entity));
211208
} catch (IOException e) {
212209
throw new ElasticsearchException("failed to build scroll entity", e);
213210
}
@@ -219,14 +216,14 @@ static Request clearScroll(String scroll, Version remoteVersion) {
219216

220217
if (remoteVersion.before(Version.fromId(2000099))) {
221218
// Versions before 2.0.0 extract the plain scroll_id from the body
222-
request.setEntity(new StringEntity(scroll, ContentType.TEXT_PLAIN));
219+
request.setEntity(new NStringEntity(scroll, ContentType.TEXT_PLAIN));
223220
return request;
224221
}
225222
try (XContentBuilder entity = JsonXContent.contentBuilder()) {
226223
entity.startObject()
227224
.array("scroll_id", scroll)
228225
.endObject();
229-
request.setEntity(new StringEntity(Strings.toString(entity), ContentType.APPLICATION_JSON));
226+
request.setJsonEntity(Strings.toString(entity));
230227
} catch (IOException e) {
231228
throw new ElasticsearchException("failed to build clear scroll entity", e);
232229
}

0 commit comments

Comments
 (0)