diff --git a/java-client/src/main/java/co/elastic/clients/elasticsearch/core/CreateRequest.java b/java-client/src/main/java/co/elastic/clients/elasticsearch/core/CreateRequest.java index 7ba197635..1cc304d4c 100644 --- a/java-client/src/main/java/co/elastic/clients/elasticsearch/core/CreateRequest.java +++ b/java-client/src/main/java/co/elastic/clients/elasticsearch/core/CreateRequest.java @@ -512,5 +512,5 @@ public static JsonpDeserializer> createCrea } return params; - }, SimpleEndpoint.emptyMap(), true, CreateResponse._DESERIALIZER); + }, SimpleEndpoint.emptyMap(), r -> r.document(), CreateResponse._DESERIALIZER); } diff --git a/java-client/src/main/java/co/elastic/clients/elasticsearch/core/IndexRequest.java b/java-client/src/main/java/co/elastic/clients/elasticsearch/core/IndexRequest.java index 7670083c3..660a4aacc 100644 --- a/java-client/src/main/java/co/elastic/clients/elasticsearch/core/IndexRequest.java +++ b/java-client/src/main/java/co/elastic/clients/elasticsearch/core/IndexRequest.java @@ -663,5 +663,5 @@ public static JsonpDeserializer> createIndex } return params; - }, SimpleEndpoint.emptyMap(), true, IndexResponse._DESERIALIZER); + }, SimpleEndpoint.emptyMap(), r -> r.document(), IndexResponse._DESERIALIZER); } diff --git a/java-client/src/main/java/co/elastic/clients/json/JsonpUtils.java b/java-client/src/main/java/co/elastic/clients/json/JsonpUtils.java index 646747049..a8449b870 100644 --- a/java-client/src/main/java/co/elastic/clients/json/JsonpUtils.java +++ b/java-client/src/main/java/co/elastic/clients/json/JsonpUtils.java @@ -150,6 +150,60 @@ public static void skipValue(JsonParser parser, Event event) { } } + /** + * Copy the JSON value at the current parser location to a JSON generator. + */ + public static void copy(JsonParser parser, JsonGenerator generator, JsonParser.Event event) { + + switch (event) { + case START_OBJECT: + generator.writeStartObject(); + while ((event = parser.next()) != Event.END_OBJECT) { + expectEvent(parser, Event.KEY_NAME, event); + generator.writeKey(parser.getString()); + copy(parser, generator, parser.next()); + } + generator.writeEnd(); + break; + + case START_ARRAY: + generator.writeStartArray(); + generator.writeStartObject(); + while ((event = parser.next()) != Event.END_ARRAY) { + copy(parser, generator, event); + } + generator.writeEnd(); + break; + + case VALUE_STRING: + generator.write(parser.getString()); + break; + + case VALUE_FALSE: + generator.write(false); + break; + + case VALUE_TRUE: + generator.write(true); + break; + + case VALUE_NULL: + generator.writeNull(); + break; + + case VALUE_NUMBER: + if (parser.isIntegralNumber()) { + generator.write(parser.getLong()); + } else { + generator.write(parser.getBigDecimal()); + } + break; + + default: + throw new UnexpectedJsonEventException(parser, event); + } + } + public static void serialize(T value, JsonGenerator generator, @Nullable JsonpSerializer serializer, JsonpMapper mapper) { if (serializer != null) { serializer.serialize(value, generator, mapper); diff --git a/java-client/src/main/java/co/elastic/clients/transport/Endpoint.java b/java-client/src/main/java/co/elastic/clients/transport/Endpoint.java index 275695d67..2ef0a0989 100644 --- a/java-client/src/main/java/co/elastic/clients/transport/Endpoint.java +++ b/java-client/src/main/java/co/elastic/clients/transport/Endpoint.java @@ -70,7 +70,23 @@ default Map headers(RequestT request) { return Collections.emptyMap(); } - boolean hasRequestBody(); + /** + * Get the body for a request. The caller must handle several cases depending on the interface implemented by the result: + *
  • + * {@code null} means the request has no body. + *
  • + *
  • + * {@link co.elastic.clients.json.NdJsonpSerializable} must be serialized as nd-json. + *
  • + *
  • + * {@link co.elastic.clients.util.BinaryData} must be serialized as is. + *
  • + *
  • + * All other objects must be serialized as JSON using a {@link co.elastic.clients.json.JsonpMapper} + *
  • + */ + @Nullable + Object body(RequestT request); /** * Is this status code to be considered as an error? @@ -90,7 +106,7 @@ default BinaryEndpoint withBinaryResponse() { this::requestUrl, this::queryParameters, this::headers, - this.hasRequestBody(), + this::body, null ); } diff --git a/java-client/src/main/java/co/elastic/clients/transport/endpoints/BinaryEndpoint.java b/java-client/src/main/java/co/elastic/clients/transport/endpoints/BinaryEndpoint.java index 76d74d6d4..5a7d52b0f 100644 --- a/java-client/src/main/java/co/elastic/clients/transport/endpoints/BinaryEndpoint.java +++ b/java-client/src/main/java/co/elastic/clients/transport/endpoints/BinaryEndpoint.java @@ -24,6 +24,19 @@ public class BinaryEndpoint extends EndpointBase { + public BinaryEndpoint( + String id, + Function method, + Function requestUrl, + Function> queryParameters, + Function> headers, + Function body, + Object ignored // same number of arguments as SimpleEndpoint + ) { + super(id, method, requestUrl, queryParameters, headers, body); + } + public BinaryEndpoint( String id, Function method, @@ -34,7 +47,7 @@ public BinaryEndpoint( boolean hasRequestBody, Object ignored // same number of arguments as SimpleEndpoint ) { - super(id, method, requestUrl, queryParameters, headers, hasRequestBody); + super(id, method, requestUrl, queryParameters, headers, hasRequestBody ? returnSelf() : returnNull()); } @Override diff --git a/java-client/src/main/java/co/elastic/clients/transport/endpoints/BooleanEndpoint.java b/java-client/src/main/java/co/elastic/clients/transport/endpoints/BooleanEndpoint.java index 398ccc386..e9c386c8e 100644 --- a/java-client/src/main/java/co/elastic/clients/transport/endpoints/BooleanEndpoint.java +++ b/java-client/src/main/java/co/elastic/clients/transport/endpoints/BooleanEndpoint.java @@ -34,7 +34,7 @@ public BooleanEndpoint( boolean hasRequestBody, Object ignored // same number of arguments as SimpleEndpoint ) { - super(id, method, requestUrl, queryParameters, headers, hasRequestBody); + super(id, method, requestUrl, queryParameters, headers, hasRequestBody ? returnSelf() : returnNull()); } @Override diff --git a/java-client/src/main/java/co/elastic/clients/transport/endpoints/DelegatingJsonEndpoint.java b/java-client/src/main/java/co/elastic/clients/transport/endpoints/DelegatingJsonEndpoint.java index cf4a8a563..d79ba91f6 100644 --- a/java-client/src/main/java/co/elastic/clients/transport/endpoints/DelegatingJsonEndpoint.java +++ b/java-client/src/main/java/co/elastic/clients/transport/endpoints/DelegatingJsonEndpoint.java @@ -58,9 +58,10 @@ public Map headers(Req request) { return endpoint.headers(request); } + @Nullable @Override - public boolean hasRequestBody() { - return endpoint.hasRequestBody(); + public Object body(Req request) { + return endpoint.body(request); } @Override diff --git a/java-client/src/main/java/co/elastic/clients/transport/endpoints/EndpointBase.java b/java-client/src/main/java/co/elastic/clients/transport/endpoints/EndpointBase.java index eac712e09..62d17b703 100644 --- a/java-client/src/main/java/co/elastic/clients/transport/endpoints/EndpointBase.java +++ b/java-client/src/main/java/co/elastic/clients/transport/endpoints/EndpointBase.java @@ -24,6 +24,7 @@ import co.elastic.clients.transport.Endpoint; import org.apache.http.client.utils.URLEncodedUtils; +import javax.annotation.Nullable; import java.util.Collections; import java.util.Map; import java.util.function.Function; @@ -31,6 +32,8 @@ public class EndpointBase implements Endpoint { private static final Function> EMPTY_MAP = x -> Collections.emptyMap(); + private static final Function RETURN_NULL = x -> null; + private static final Function RETURN_SELF = x -> x; /** * Returns a function that always returns an empty String to String map. Useful to avoid creating lots of @@ -41,12 +44,29 @@ public static Function> emptyMap() { return (Function>) EMPTY_MAP; } + /** + * Returns a function that always returns {@code null}. + */ + @SuppressWarnings("unchecked") + static Function returnNull() { + return (Function) RETURN_NULL; + } + + /** + * Returns a function that always returns its parameter. It's similar to {@code Function.identity()} with the difference + * that the input and output generic parameters are different, making it suitable for use in a wider range of use cases. + */ + @SuppressWarnings("unchecked") + static Function returnSelf() { + return (Function) RETURN_SELF; + } + protected final String id; protected final Function method; protected final Function requestUrl; protected final Function> queryParameters; protected final Function> headers; - protected final boolean hasRequestBody; + protected final Function body; public EndpointBase( String id, @@ -54,14 +74,14 @@ public EndpointBase( Function requestUrl, Function> queryParameters, Function> headers, - boolean hasRequestBody + Function body ) { this.id = id; this.method = method; this.requestUrl = requestUrl; this.queryParameters = queryParameters; this.headers = headers; - this.hasRequestBody = hasRequestBody; + this.body = body; } @Override @@ -89,9 +109,10 @@ public Map headers(RequestT request) { return this.headers.apply(request); } + @Nullable @Override - public boolean hasRequestBody() { - return this.hasRequestBody; + public Object body(RequestT request) { + return this.body.apply(request); } // ES-specific @@ -114,7 +135,7 @@ public SimpleEndpoint withResponseDeseria requestUrl, queryParameters, headers, - hasRequestBody, + body, newResponseParser ); } diff --git a/java-client/src/main/java/co/elastic/clients/transport/endpoints/SimpleEndpoint.java b/java-client/src/main/java/co/elastic/clients/transport/endpoints/SimpleEndpoint.java index 97c774aa1..9e8041dcb 100644 --- a/java-client/src/main/java/co/elastic/clients/transport/endpoints/SimpleEndpoint.java +++ b/java-client/src/main/java/co/elastic/clients/transport/endpoints/SimpleEndpoint.java @@ -24,24 +24,12 @@ import co.elastic.clients.transport.JsonEndpoint; import org.apache.http.client.utils.URLEncodedUtils; -import java.util.Collections; import java.util.Map; import java.util.function.Function; public class SimpleEndpoint extends EndpointBase implements JsonEndpoint { - private static final Function> EMPTY_MAP = x -> Collections.emptyMap(); - - /** - * Returns a function that always returns an empty String to String map. Useful to avoid creating lots of - * duplicate lambdas in endpoints that don't have headers or parameters. - */ - @SuppressWarnings("unchecked") - public static Function> emptyMap() { - return (Function>) EMPTY_MAP; - } - private final JsonpDeserializer responseParser; public SimpleEndpoint( @@ -50,13 +38,33 @@ public SimpleEndpoint( Function requestUrl, Function> queryParameters, Function> headers, - boolean hasRequestBody, + Function body, JsonpDeserializer responseParser ) { - super(id, method, requestUrl, queryParameters, headers, hasRequestBody); + super(id, method, requestUrl, queryParameters, headers, body); this.responseParser = responseParser; } + public SimpleEndpoint( + String id, + Function method, + Function requestUrl, + Function> queryParameters, + Function> headers, + boolean hasResponseBody, + JsonpDeserializer responseParser + ) { + this( + id, + method, + requestUrl, + queryParameters, + headers, + hasResponseBody ? returnSelf() : returnNull(), + responseParser + ); + } + @Override public JsonpDeserializer responseDeserializer() { return this.responseParser; @@ -76,7 +84,7 @@ public SimpleEndpoint withResponseDeseria requestUrl, queryParameters, headers, - hasRequestBody, + body, newResponseParser ); } diff --git a/java-client/src/main/java/co/elastic/clients/transport/rest_client/RestClientTransport.java b/java-client/src/main/java/co/elastic/clients/transport/rest_client/RestClientTransport.java index d884d190f..255cd8e9f 100644 --- a/java-client/src/main/java/co/elastic/clients/transport/rest_client/RestClientTransport.java +++ b/java-client/src/main/java/co/elastic/clients/transport/rest_client/RestClientTransport.java @@ -59,6 +59,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -215,21 +216,41 @@ private org.elasticsearch.client.Request prepareLowLevelRequest( clientReq.addParameters(params); - if (endpoint.hasRequestBody()) { - // Request has a body and must implement JsonpSerializable or NdJsonpSerializable - - if (request instanceof NdJsonpSerializable) { + Object body = endpoint.body(request); + if (body != null) { + // Request has a body + if (body instanceof NdJsonpSerializable) { List lines = new ArrayList<>(); - collectNdJsonLines(lines, (NdJsonpSerializable)request); + collectNdJsonLines(lines, (NdJsonpSerializable) request); clientReq.setEntity(new MultiBufferEntity(lines, JsonContentType)); + + } else if (body instanceof BinaryData) { + BinaryData data = (BinaryData)body; + + // ES expects the Accept and Content-Type headers to be consistent. + ContentType contentType; + String dataContentType = data.contentType(); + if (co.elastic.clients.util.ContentType.APPLICATION_JSON.equals(dataContentType)) { + // Fast path + contentType = JsonContentType; + } else { + contentType = ContentType.parse(dataContentType); + } + + clientReq.setEntity(new MultiBufferEntity( + Collections.singletonList(data.asByteBuffer()), + contentType + )); + } else { ByteArrayOutputStream baos = new ByteArrayOutputStream(); JsonGenerator generator = mapper.jsonProvider().createGenerator(baos); - mapper.serialize(request, generator); + mapper.serialize(body, generator); generator.close(); clientReq.setEntity(new ByteArrayEntity(baos.toByteArray(), JsonContentType)); } } + // Request parameter intercepted by LLRC clientReq.addParameter("ignore", "400,401,403,404,405"); return clientReq; diff --git a/java-client/src/main/java/co/elastic/clients/util/BinaryData.java b/java-client/src/main/java/co/elastic/clients/util/BinaryData.java index 500f16284..02ec646b1 100644 --- a/java-client/src/main/java/co/elastic/clients/util/BinaryData.java +++ b/java-client/src/main/java/co/elastic/clients/util/BinaryData.java @@ -19,18 +19,28 @@ package co.elastic.clients.util; +import co.elastic.clients.json.JsonpDeserializable; +import co.elastic.clients.json.JsonpDeserializer; +import co.elastic.clients.json.JsonpDeserializerBase; import co.elastic.clients.json.JsonpMapper; import jakarta.json.stream.JsonGenerator; +import jakarta.json.stream.JsonParser; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; /** - * Binary data representing a serialized value. + * Binary data with an associated content type. */ +@JsonpDeserializable public interface BinaryData { + /** + * The content type. + */ + String contentType(); + /** * Write this data to an output stream. */ @@ -52,6 +62,9 @@ public interface BinaryData { /** * Create a {@code BinaryData} from a value and a JSON mapper. The binary content is the result of serializing * {@code value} with {@code mapper}. Returns {@code null} if {@code value} is null. + *

    + * Note that the result's content-type can be different from {@code "application/json"} if the JSON mapper is setup to + * produce other representations such as CBOR or SMILE. */ static BinaryData of(Object value, JsonpMapper mapper) { if (value == null) { @@ -67,42 +80,23 @@ static BinaryData of(Object value, JsonpMapper mapper) { mapper.serialize(value, generator); generator.close(); - return new ByteArrayBinaryData(out.array(), 0, out.size()); + return new ByteArrayBinaryData(out.array(), 0, out.size(), ContentType.APPLICATION_JSON); } - static BinaryData of(byte[] bytes) { - return new ByteArrayBinaryData(bytes, 0, bytes.length); + static BinaryData of(byte[] bytes, String contentType) { + return new ByteArrayBinaryData(bytes, 0, bytes.length, contentType); } - static BinaryData of(byte[] value, int offset, int length) { - return new ByteArrayBinaryData(value, offset, length); + static BinaryData of(byte[] value, int offset, int length, String contentType) { + return new ByteArrayBinaryData(value, offset, length, contentType); } - class ByteArrayBinaryData implements BinaryData { - - private final byte[] bytes; - private final int offset; - private final int length; - - ByteArrayBinaryData(byte[] bytes, int offset, int length) { - this.bytes = bytes; - this.offset = offset; - this.length = length; - } - + JsonpDeserializer _DESERIALIZER = new JsonpDeserializerBase( + ByteArrayBinaryData._DESERIALIZER.acceptedEvents() + ) { @Override - public void writeTo(OutputStream out) throws IOException { - out.write(bytes, offset, length); + public BinaryData deserialize(JsonParser parser, JsonpMapper mapper, JsonParser.Event event) { + return ByteArrayBinaryData._DESERIALIZER.deserialize(parser, mapper, event); } - - @Override - public long size() { - return length; - } - - @Override - public ByteBuffer asByteBuffer() { - return ByteBuffer.wrap(bytes, offset, length); - } - } + }; } diff --git a/java-client/src/main/java/co/elastic/clients/util/ByteArrayBinaryData.java b/java-client/src/main/java/co/elastic/clients/util/ByteArrayBinaryData.java new file mode 100644 index 000000000..4b128a2e3 --- /dev/null +++ b/java-client/src/main/java/co/elastic/clients/util/ByteArrayBinaryData.java @@ -0,0 +1,96 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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 co.elastic.clients.util; + +import co.elastic.clients.json.JsonpDeserializable; +import co.elastic.clients.json.JsonpDeserializer; +import co.elastic.clients.json.JsonpDeserializerBase; +import co.elastic.clients.json.JsonpMapper; +import co.elastic.clients.json.JsonpUtils; +import jakarta.json.stream.JsonGenerator; +import jakarta.json.stream.JsonParser; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.util.EnumSet; + +@JsonpDeserializable +public class ByteArrayBinaryData implements BinaryData { + + private final byte[] bytes; + private final int offset; + private final int length; + private final String contentType; + + ByteArrayBinaryData(byte[] bytes, int offset, int length, String contentType) { + this.contentType = contentType; + this.bytes = bytes; + this.offset = offset; + this.length = length; + } + + ByteArrayBinaryData(byte[] bytes, String contentType) { + this.contentType = contentType; + this.bytes = bytes; + this.offset = 0; + this.length = bytes.length; + } + + + @Override + public String contentType() { + return this.contentType; + } + + @Override + public void writeTo(OutputStream out) throws IOException { + out.write(bytes, offset, length); + } + + @Override + public long size() { + return length; + } + + @Override + public ByteBuffer asByteBuffer() { + return ByteBuffer.wrap(bytes, offset, length); + } + + private static class Deserializer extends JsonpDeserializerBase { + + Deserializer() { + super(EnumSet.allOf(JsonParser.Event.class)); + } + + @Override + public ByteArrayBinaryData deserialize(JsonParser parser, JsonpMapper mapper, JsonParser.Event event) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + JsonGenerator generator = mapper.jsonProvider().createGenerator(baos); + JsonpUtils.copy(parser, generator, event); + generator.close(); + return new ByteArrayBinaryData(baos.toByteArray(), ContentType.APPLICATION_JSON); + } + } + + public static final JsonpDeserializer _DESERIALIZER = new Deserializer(); +} diff --git a/java-client/src/main/java/co/elastic/clients/util/ContentType.java b/java-client/src/main/java/co/elastic/clients/util/ContentType.java new file mode 100644 index 000000000..298372a41 --- /dev/null +++ b/java-client/src/main/java/co/elastic/clients/util/ContentType.java @@ -0,0 +1,30 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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 co.elastic.clients.util; + +/** + * Constants for content-type values. + */ +public class ContentType { + + private ContentType() {} + + public static final String APPLICATION_JSON = "application/json"; +} diff --git a/java-client/src/test/java/co/elastic/clients/documentation/usage/IndexingBulkTest.java b/java-client/src/test/java/co/elastic/clients/documentation/usage/IndexingBulkTest.java index 8b514135a..5e2572193 100644 --- a/java-client/src/test/java/co/elastic/clients/documentation/usage/IndexingBulkTest.java +++ b/java-client/src/test/java/co/elastic/clients/documentation/usage/IndexingBulkTest.java @@ -28,6 +28,7 @@ import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem; import co.elastic.clients.elasticsearch.model.ModelTestCase; import co.elastic.clients.util.BinaryData; +import co.elastic.clients.util.ContentType; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -109,7 +110,7 @@ public void indexBulkJson() throws Exception { for (File file: logFiles) { FileInputStream input = new FileInputStream(file); - BinaryData data = BinaryData.of(IOUtils.toByteArray(input)); + BinaryData data = BinaryData.of(IOUtils.toByteArray(input), ContentType.APPLICATION_JSON); br.operations(op -> op .index(idx -> idx @@ -138,7 +139,7 @@ public void useBulkIndexer() throws Exception { for (File file: logFiles) { FileInputStream input = new FileInputStream(file); - BinaryData data = BinaryData.of(IOUtils.toByteArray(input)); + BinaryData data = BinaryData.of(IOUtils.toByteArray(input), ContentType.APPLICATION_JSON); ingester.add(op -> op // <4> .index(idx -> idx @@ -194,7 +195,7 @@ public void afterBulk(long executionId, BulkRequest request, List contex for (File file: logFiles) { FileInputStream input = new FileInputStream(file); - BinaryData data = BinaryData.of(IOUtils.toByteArray(input)); + BinaryData data = BinaryData.of(IOUtils.toByteArray(input), ContentType.APPLICATION_JSON); ingester.add(op -> op .index(idx -> idx diff --git a/java-client/src/test/java/co/elastic/clients/elasticsearch/end_to_end/RequestTest.java b/java-client/src/test/java/co/elastic/clients/elasticsearch/end_to_end/RequestTest.java index b3d16e84f..cf574626e 100644 --- a/java-client/src/test/java/co/elastic/clients/elasticsearch/end_to_end/RequestTest.java +++ b/java-client/src/test/java/co/elastic/clients/elasticsearch/end_to_end/RequestTest.java @@ -44,6 +44,8 @@ import co.elastic.clients.elasticsearch.indices.IndexState; import co.elastic.clients.elasticsearch.model.ModelTestCase; import co.elastic.clients.transport.endpoints.BooleanResponse; +import co.elastic.clients.util.BinaryData; +import co.elastic.clients.util.ContentType; import co.elastic.clients.util.DateTime; import com.fasterxml.jackson.core.type.TypeReference; import org.junit.jupiter.api.Assertions; @@ -51,6 +53,7 @@ import org.junit.jupiter.api.Test; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.time.Instant; import java.time.format.DateTimeFormatter; import java.util.Collections; @@ -198,6 +201,33 @@ public void testDataIngestion() throws Exception { assertEquals(404, msearch.responses().get(1).failure().status()); } + @Test + public void testBinaryDataIngestion() throws IOException { + String index = "binary-ingestion-test"; + String id = "foo-bar"; + + BinaryData data = BinaryData.of("{\"foo\":\"bar\"}".getBytes(), ContentType.APPLICATION_JSON); + + client.index(i -> i + .index(index) + .id(id) + .document(data) + .refresh(Refresh.True) + ); + + GetResponse getResponse = client.get(g -> g + .index(index) + .id(id) + , BinaryData.class + ); + + assertEquals(id, getResponse.id()); + assertEquals( + "{\"foo\":\"bar\"}", + new String(getResponse.source().asByteBuffer().array(), StandardCharsets.UTF_8) + ); + } + @Test public void testMappingWithType() throws IOException { String index = "mapping-with-type"; diff --git a/java-client/src/test/java/co/elastic/clients/transport/endpoints/BooleanEndpointTest.java b/java-client/src/test/java/co/elastic/clients/transport/endpoints/BooleanEndpointTest.java index 769195044..1c1b3dfc7 100644 --- a/java-client/src/test/java/co/elastic/clients/transport/endpoints/BooleanEndpointTest.java +++ b/java-client/src/test/java/co/elastic/clients/transport/endpoints/BooleanEndpointTest.java @@ -20,7 +20,7 @@ package co.elastic.clients.transport.endpoints; import co.elastic.clients.elasticsearch.core.ExistsRequest; -import co.elastic.clients.elasticsearch.logstash.PutPipelineRequest; +import co.elastic.clients.elasticsearch.security.SamlCompleteLogoutRequest; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -28,7 +28,10 @@ public class BooleanEndpointTest extends Assertions { @Test public void testHasRequestBody() { - assertFalse(ExistsRequest._ENDPOINT.hasRequestBody()); - assertTrue(PutPipelineRequest._ENDPOINT.hasRequestBody()); + ExistsRequest er = ExistsRequest.of(r -> r.index("foo").id("1")); + assertNull(ExistsRequest._ENDPOINT.body(er)); + + SamlCompleteLogoutRequest sclr = SamlCompleteLogoutRequest.of(r -> r.ids("1").realm("r")); + assertNotNull(SamlCompleteLogoutRequest._ENDPOINT.body(sclr)); } }