From 3331fcf252ccc52e937f5df842b153cdbda5d59a Mon Sep 17 00:00:00 2001 From: David Pilato Date: Mon, 21 Mar 2022 15:19:31 +0100 Subject: [PATCH 1/5] Add serializeToString method This will allow generating Json String documents out of the box from any of the response/request objects. --- .../clients/json/DelegatingJsonpMapper.java | 5 ++ .../co/elastic/clients/json/JsonpMapper.java | 8 ++++ .../elastic/clients/json/JsonpMapperBase.java | 19 ++++++++ .../clients/json/SerializeToStringTest.java | 48 +++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java diff --git a/java-client/src/main/java/co/elastic/clients/json/DelegatingJsonpMapper.java b/java-client/src/main/java/co/elastic/clients/json/DelegatingJsonpMapper.java index 708bd442a..09b6608ee 100644 --- a/java-client/src/main/java/co/elastic/clients/json/DelegatingJsonpMapper.java +++ b/java-client/src/main/java/co/elastic/clients/json/DelegatingJsonpMapper.java @@ -48,6 +48,11 @@ public void serialize(T value, JsonGenerator generator) { mapper.serialize(value, generator); } + @Override + public String serializeToString(T value) { + return mapper.serializeToString(value); + } + @Override public boolean ignoreUnknownFields() { return mapper.ignoreUnknownFields(); diff --git a/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java b/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java index a47992b9b..cf82ea266 100644 --- a/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java +++ b/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java @@ -19,11 +19,14 @@ package co.elastic.clients.json; +import co.elastic.clients.json.jackson.JacksonJsonProvider; +import co.elastic.clients.json.jackson.JacksonJsonpMapper; import jakarta.json.spi.JsonProvider; import jakarta.json.stream.JsonGenerator; import jakarta.json.stream.JsonParser; import javax.annotation.Nullable; +import java.io.StringWriter; /** * A {@code JsonpMapper} combines a JSON-P provider and object serialization/deserialization based on JSON-P events. @@ -51,6 +54,11 @@ public interface JsonpMapper { */ void serialize(T value, JsonGenerator generator); + /** + * Serialize an object to its Json String representation + */ + String serializeToString(T value); + /** * Should object parsers in the API client be lenient and silently ignore unknown fields? * diff --git a/java-client/src/main/java/co/elastic/clients/json/JsonpMapperBase.java b/java-client/src/main/java/co/elastic/clients/json/JsonpMapperBase.java index 3f7e6b110..301859726 100644 --- a/java-client/src/main/java/co/elastic/clients/json/JsonpMapperBase.java +++ b/java-client/src/main/java/co/elastic/clients/json/JsonpMapperBase.java @@ -19,11 +19,14 @@ package co.elastic.clients.json; +import jakarta.json.JsonException; import jakarta.json.JsonValue; +import jakarta.json.spi.JsonProvider; import jakarta.json.stream.JsonGenerator; import jakarta.json.stream.JsonParser; import javax.annotation.Nullable; +import java.io.StringWriter; import java.lang.reflect.Field; public abstract class JsonpMapperBase implements JsonpMapper { @@ -76,6 +79,22 @@ public static JsonpSerializer findSerializer(T value) { return null; } + @Override + public String serializeToString(T value) { + JsonpSerializer serializer = findSerializer(value); + + if (serializer != null) { + StringWriter writer = new StringWriter(); + serializer.serialize(value, jsonProvider().createGenerator(writer), this); + return writer.toString(); + } else { + throw new JsonException( + "Cannot find a serializer for type " + value.getClass().getName() + + ". Consider using a full-featured JsonpMapper" + ); + } + } + protected static class JsonpSerializableSerializer implements JsonpSerializer { @Override public void serialize(T value, JsonGenerator generator, JsonpMapper mapper) { diff --git a/java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java b/java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java new file mode 100644 index 000000000..1353ccd8a --- /dev/null +++ b/java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java @@ -0,0 +1,48 @@ +/* + * 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.json; + +import co.elastic.clients.elasticsearch._types.Result; +import co.elastic.clients.elasticsearch.core.IndexResponse; +import co.elastic.clients.elasticsearch.model.ModelTestCase; +import co.elastic.clients.json.jackson.JacksonJsonpMapper; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +public class SerializeToStringTest extends ModelTestCase { + + @Test + public void testRequestWithGenericValueBody() { + IndexResponse resp = IndexResponse.of(r -> r + .index("foo") + .id("1") + .primaryTerm(1) + .seqNo(1) + .version(1) + .shards(s -> s.successful(1).failed(0).total(1)) + .result(Result.Created) + ); + + String json = mapper.serializeToString(resp); + + assertEquals("foo", json); + } +} + From 807b74267964e4ea10e185c1ef7adb285d66b849 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Mon, 21 Mar 2022 18:15:04 +0100 Subject: [PATCH 2/5] Fix tests --- .../elastic/clients/json/JsonpMapperBase.java | 5 +++- .../clients/json/SerializeToStringTest.java | 25 +++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/java-client/src/main/java/co/elastic/clients/json/JsonpMapperBase.java b/java-client/src/main/java/co/elastic/clients/json/JsonpMapperBase.java index 301859726..4763c8424 100644 --- a/java-client/src/main/java/co/elastic/clients/json/JsonpMapperBase.java +++ b/java-client/src/main/java/co/elastic/clients/json/JsonpMapperBase.java @@ -26,6 +26,7 @@ import jakarta.json.stream.JsonParser; import javax.annotation.Nullable; +import java.io.IOException; import java.io.StringWriter; import java.lang.reflect.Field; @@ -85,7 +86,9 @@ public String serializeToString(T value) { if (serializer != null) { StringWriter writer = new StringWriter(); - serializer.serialize(value, jsonProvider().createGenerator(writer), this); + JsonGenerator generator = jsonProvider().createGenerator(writer); + serializer.serialize(value, generator, this); + generator.close(); return writer.toString(); } else { throw new JsonException( diff --git a/java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java b/java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java index 1353ccd8a..52fb4ca58 100644 --- a/java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java +++ b/java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java @@ -21,15 +21,19 @@ import co.elastic.clients.elasticsearch._types.Result; import co.elastic.clients.elasticsearch.core.IndexResponse; +import co.elastic.clients.elasticsearch.core.SearchResponse; +import co.elastic.clients.elasticsearch.core.search.TotalHitsRelation; import co.elastic.clients.elasticsearch.model.ModelTestCase; import co.elastic.clients.json.jackson.JacksonJsonpMapper; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; +import java.util.Collections; + public class SerializeToStringTest extends ModelTestCase { @Test - public void testRequestWithGenericValueBody() { + public void testIndexResponse() { IndexResponse resp = IndexResponse.of(r -> r .index("foo") .id("1") @@ -42,7 +46,24 @@ public void testRequestWithGenericValueBody() { String json = mapper.serializeToString(resp); - assertEquals("foo", json); + assertEquals("{\"_id\":\"1\",\"_index\":\"foo\",\"_primary_term\":1,\"result\":\"created\",\"_seq_no\":1,\"_shards\":{\"failed\":0.0,\"successful\":1.0,\"total\":1.0},\"_version\":1}", json); + } + + @Test + public void testSearchResponse() { + SearchResponse resp = SearchResponse.searchResponseOf(r -> r + .took(10) + .shards(s -> s.successful(1).failed(0).total(1)) + .timedOut(false) + .hits(h -> h + .total(t -> t.value(0).relation(TotalHitsRelation.Eq)) + .hits(Collections.emptyList()) + ) + ); + + String json = mapper.serializeToString(resp); + + assertEquals("{\"took\":10,\"timed_out\":false,\"_shards\":{\"failed\":0.0,\"successful\":1.0,\"total\":1.0},\"hits\":{\"total\":{\"relation\":\"eq\",\"value\":0},\"hits\":[]}}", json); } } From ae598b3bf88c25fcd76bbcfce6ff25293c4744e8 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Mon, 21 Mar 2022 18:18:47 +0100 Subject: [PATCH 3/5] Move tests to JsonDataTest --- .../elasticsearch/json/JsonDataTest.java | 39 +++++++++++ .../clients/json/SerializeToStringTest.java | 69 ------------------- 2 files changed, 39 insertions(+), 69 deletions(-) delete mode 100644 java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java diff --git a/java-client/src/test/java/co/elastic/clients/elasticsearch/json/JsonDataTest.java b/java-client/src/test/java/co/elastic/clients/elasticsearch/json/JsonDataTest.java index e9cfed2eb..e29f9b832 100644 --- a/java-client/src/test/java/co/elastic/clients/elasticsearch/json/JsonDataTest.java +++ b/java-client/src/test/java/co/elastic/clients/elasticsearch/json/JsonDataTest.java @@ -20,6 +20,10 @@ package co.elastic.clients.elasticsearch.json; import co.elastic.clients.elasticsearch.ElasticsearchClient; +import co.elastic.clients.elasticsearch._types.Result; +import co.elastic.clients.elasticsearch.core.IndexResponse; +import co.elastic.clients.elasticsearch.core.SearchResponse; +import co.elastic.clients.elasticsearch.core.search.TotalHitsRelation; import co.elastic.clients.elasticsearch.indices.CreateIndexRequest; import co.elastic.clients.json.DelegatingDeserializer; import co.elastic.clients.json.JsonData; @@ -40,6 +44,7 @@ import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; +import java.util.Collections; public class JsonDataTest extends Assert { @@ -125,4 +130,38 @@ public void testConvert() { assertEquals(JsonValue.ValueType.STRING, value.getValueType()); assertEquals("foo", ((JsonString)value).getString()); } + + @Test + public void testIndexResponse() { + IndexResponse resp = IndexResponse.of(r -> r + .index("foo") + .id("1") + .primaryTerm(1) + .seqNo(1) + .version(1) + .shards(s -> s.successful(1).failed(0).total(1)) + .result(Result.Created) + ); + + String json = new JacksonJsonpMapper().serializeToString(resp); + + assertEquals("{\"_id\":\"1\",\"_index\":\"foo\",\"_primary_term\":1,\"result\":\"created\",\"_seq_no\":1,\"_shards\":{\"failed\":0.0,\"successful\":1.0,\"total\":1.0},\"_version\":1}", json); + } + + @Test + public void testSearchResponse() { + SearchResponse resp = SearchResponse.searchResponseOf(r -> r + .took(10) + .shards(s -> s.successful(1).failed(0).total(1)) + .timedOut(false) + .hits(h -> h + .total(t -> t.value(0).relation(TotalHitsRelation.Eq)) + .hits(Collections.emptyList()) + ) + ); + + String json = new JacksonJsonpMapper().serializeToString(resp); + + assertEquals("{\"took\":10,\"timed_out\":false,\"_shards\":{\"failed\":0.0,\"successful\":1.0,\"total\":1.0},\"hits\":{\"total\":{\"relation\":\"eq\",\"value\":0},\"hits\":[]}}", json); + } } diff --git a/java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java b/java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java deleted file mode 100644 index 52fb4ca58..000000000 --- a/java-client/src/test/java/co/elastic/clients/json/SerializeToStringTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.json; - -import co.elastic.clients.elasticsearch._types.Result; -import co.elastic.clients.elasticsearch.core.IndexResponse; -import co.elastic.clients.elasticsearch.core.SearchResponse; -import co.elastic.clients.elasticsearch.core.search.TotalHitsRelation; -import co.elastic.clients.elasticsearch.model.ModelTestCase; -import co.elastic.clients.json.jackson.JacksonJsonpMapper; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Test; - -import java.util.Collections; - -public class SerializeToStringTest extends ModelTestCase { - - @Test - public void testIndexResponse() { - IndexResponse resp = IndexResponse.of(r -> r - .index("foo") - .id("1") - .primaryTerm(1) - .seqNo(1) - .version(1) - .shards(s -> s.successful(1).failed(0).total(1)) - .result(Result.Created) - ); - - String json = mapper.serializeToString(resp); - - assertEquals("{\"_id\":\"1\",\"_index\":\"foo\",\"_primary_term\":1,\"result\":\"created\",\"_seq_no\":1,\"_shards\":{\"failed\":0.0,\"successful\":1.0,\"total\":1.0},\"_version\":1}", json); - } - - @Test - public void testSearchResponse() { - SearchResponse resp = SearchResponse.searchResponseOf(r -> r - .took(10) - .shards(s -> s.successful(1).failed(0).total(1)) - .timedOut(false) - .hits(h -> h - .total(t -> t.value(0).relation(TotalHitsRelation.Eq)) - .hits(Collections.emptyList()) - ) - ); - - String json = mapper.serializeToString(resp); - - assertEquals("{\"took\":10,\"timed_out\":false,\"_shards\":{\"failed\":0.0,\"successful\":1.0,\"total\":1.0},\"hits\":{\"total\":{\"relation\":\"eq\",\"value\":0},\"hits\":[]}}", json); - } -} - From dacdaf7611bc6b7d33e55e2c58597763bf0f5764 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Thu, 24 Mar 2022 19:21:07 +0100 Subject: [PATCH 4/5] Update java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java Co-authored-by: Sylvain Wallez --- .../main/java/co/elastic/clients/json/JsonpMapper.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java b/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java index cf82ea266..65dc01082 100644 --- a/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java +++ b/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java @@ -57,7 +57,13 @@ public interface JsonpMapper { /** * Serialize an object to its Json String representation */ - String serializeToString(T value); + default String serializeToString(T value) { + StringWriter writer = new StringWriter(); + try (JsonGenerator generator = jsonProvider().createGenerator(writer)) { + serialize(value, generator); + }; + return writer.toString(); + } /** * Should object parsers in the API client be lenient and silently ignore unknown fields? From 144ccdb2e50910b84c7fae667ca0304b0927b2d2 Mon Sep 17 00:00:00 2001 From: David Pilato Date: Thu, 24 Mar 2022 19:21:11 +0100 Subject: [PATCH 5/5] Update java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java Co-authored-by: Sylvain Wallez --- .../src/main/java/co/elastic/clients/json/JsonpMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java b/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java index 65dc01082..ed2629185 100644 --- a/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java +++ b/java-client/src/main/java/co/elastic/clients/json/JsonpMapper.java @@ -55,7 +55,7 @@ public interface JsonpMapper { void serialize(T value, JsonGenerator generator); /** - * Serialize an object to its Json String representation + * Serialize an object to its JSON String representation */ default String serializeToString(T value) { StringWriter writer = new StringWriter();