diff --git a/CHANGELOG.md b/CHANGELOG.md index 9662556449..b68fb7b9d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,7 +53,7 @@ This section is for maintaining a changelog for all breaking changes for the cli - Added `queryImage` (query_image) field to `NeuralQuery`, following definition in ([Neural Query](https://opensearch.org/docs/latest/query-dsl/specialized/neural/)) ([#1137](https://github.com/opensearch-project/opensearch-java/pull/1138)) - Added `cancelAfterTimeInterval` to `SearchRequest` and `MsearchRequest` ([#1147](https://github.com/opensearch-project/opensearch-java/pull/1147)) - Added the `ml` namespace operations ([#1158](https://github.com/opensearch-project/opensearch-java/pull/1158)) -- Added `PlainDeserializable` with `withJson` method for streamlining deserialization ([#1148](https://github.com/opensearch-project/opensearch-java/pull/1148)) +- Added `IndexTemplateMapping.Builder#withJson`, `SourceField.Builder#withJson` and `IndexSettings.Builder#withJson` for streamlining deserialization ([#1148](https://github.com/opensearch-project/opensearch-java/pull/1148)) ### Dependencies - Bumps `commons-logging:commons-logging` from 1.3.3 to 1.3.4 diff --git a/guides/json.md b/guides/json.md index 3f4acd42c8..74cbf826be 100644 --- a/guides/json.md +++ b/guides/json.md @@ -2,6 +2,9 @@ - [Serialization](#serialization) - [Using toJsonString](#using-tojsonstring) - [Manual Serialization](#manual-serialization) + - [Deserialization](#deserialization) + - [Using withJson](#using-withjson) + - [Using static _DESERIALIZER](#using-static-_deserializer) # Working With JSON @@ -50,4 +53,44 @@ private String toJson(JsonpSerializable object) { throw new UncheckedIOException(ex); } } +``` + +## Deserialization + +For demonstration let's consider an IndexTemplateMapping JSON String. + +```java + +String stringTemplate = + "{\"mappings\":{\"properties\":{\"age\":{\"type\":\"integer\"}}},\"settings\":{\"number_of_shards\":\"2\",\"number_of_replicas\":\"1\"}}"; +``` +### Using withJson +For classes, Builders of which implements `PlainDeserializable` interface, a default `withJson` method is provided. +The withJson method returns the Builder enabling you to chain Builder methods for additional configuration. +This implementation uses `jakarta.json.spi.JsonProvider` SPI to discover the available JSON provider instance +from the classpath and to create a new mapper. The `JsonpUtils` utility class streamlines this deserialization process. +The following code example demonstrates how to use the `withJson` method to deserialize objects: + +```java +InputStream inputStream = new ByteArrayInputStream(stringTemplate.getBytes(StandardCharsets.UTF_8)); +IndexTemplateMapping indexTemplateMapping = new IndexTemplateMapping.Builder().withJson(inputStream).build(); +``` + + +### Using static _DESERIALIZER +For classes annotated with `@JsonpDeserializable`, a static field _DESERIALIZER is provided, +which takes a mapper and a parser as arguments and returns the instance of the json value passed in the parser. +Notice that this way you cannot further customize the instance, the state of which will solely depend on the json value parsed. + +The following sample code demonstrates how to serialize an instance of a Java class: + +```java +private IndexTemplateMapping getInstance(String templateJsonString) { + InputStream inputStream = new ByteArrayInputStream(templateJsonString.getBytes(StandardCharsets.UTF_8)); + JsonbJsonpMapper mapper = new JsonbJsonpMapper(); + try (JsonParser parser = mapper.jsonProvider().createParser(inputStream)) { + IndexTemplateMapping indexTemplateMapping = new IndexTemplateMapping._DESERIALIZER.deserialize(parser, mapper); + return indexTemplateMapping; + } +} ``` \ No newline at end of file diff --git a/java-client/src/main/java/org/opensearch/client/json/JsonpUtils.java b/java-client/src/main/java/org/opensearch/client/json/JsonpUtils.java index d9cfdaf306..4a0ff47a3d 100644 --- a/java-client/src/main/java/org/opensearch/client/json/JsonpUtils.java +++ b/java-client/src/main/java/org/opensearch/client/json/JsonpUtils.java @@ -68,7 +68,7 @@ static JsonProvider provider() { return JsonProvider.provider(); } - static final JsonpMapper DEFAULT_JSONP_MAPPER = new JsonpMapperBase() { + public static final JsonpMapper DEFAULT_JSONP_MAPPER = new JsonpMapperBase() { @Override public JsonProvider jsonProvider() { return DEFAULT_PROVIDER; diff --git a/java-client/src/main/java/org/opensearch/client/json/PlainDeserializable.java b/java-client/src/main/java/org/opensearch/client/json/PlainDeserializable.java index 12793701a4..d8890e2913 100644 --- a/java-client/src/main/java/org/opensearch/client/json/PlainDeserializable.java +++ b/java-client/src/main/java/org/opensearch/client/json/PlainDeserializable.java @@ -38,8 +38,9 @@ default B withJson(JsonParser parser, JsonpMapper mapper) { * **/ default B withJson(InputStream inputStream) { JsonpMapper defaultMapper = JsonpUtils.DEFAULT_JSONP_MAPPER; - JsonParser parser = defaultMapper.jsonProvider().createParser(inputStream); - return withJson(parser, defaultMapper); + try (JsonParser parser = defaultMapper.jsonProvider().createParser(inputStream)) { + return withJson(parser, defaultMapper); + } } /** Updates object with newly provided JSON properties @@ -48,8 +49,9 @@ default B withJson(InputStream inputStream) { * **/ default B withJson(Reader reader) { JsonpMapper defaultMapper = JsonpUtils.DEFAULT_JSONP_MAPPER; - JsonParser parser = defaultMapper.jsonProvider().createParser(reader); - return withJson(parser, defaultMapper); + try (JsonParser parser = defaultMapper.jsonProvider().createParser(reader)) { + return withJson(parser, defaultMapper); + } } } diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/json/PlainDeserializableTest.java b/java-client/src/test/java/org/opensearch/client/opensearch/json/PlainDeserializableTest.java index 4df9d60e36..d1f1faafc7 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/json/PlainDeserializableTest.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/json/PlainDeserializableTest.java @@ -8,6 +8,8 @@ package org.opensearch.client.opensearch.json; +import static org.junit.Assert.assertEquals; + import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; @@ -34,9 +36,9 @@ public void testWithJsonPutIndexTemplateRequest() { List expectedIndexPatterns = Arrays.asList("index_pattern1"); String expectedNumberOfShards = "2"; - assert expectedName.equals(indexTemplateRequest.name()); - assert expectedIndexPatterns.equals(indexTemplateRequest.indexPatterns()); - assert expectedNumberOfShards.equals(indexTemplateRequest.template().settings().numberOfShards()); + assertEquals(indexTemplateRequest.name(), expectedName); + assertEquals(expectedIndexPatterns, indexTemplateRequest.indexPatterns()); + assertEquals(expectedNumberOfShards, indexTemplateRequest.template().settings().numberOfShards()); } } diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/json/PlainJsonSerializableTest.java b/java-client/src/test/java/org/opensearch/client/opensearch/json/PlainJsonSerializableTest.java index 7fbf6ec61c..8386dc04d5 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/json/PlainJsonSerializableTest.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/json/PlainJsonSerializableTest.java @@ -52,7 +52,7 @@ public void testIndexResponse() { // Test SearchRequest which implements PlainJsonSerializable @Test - public void testSearchResponse() { + public void testSearchRequest() { String expectedStringValue = "{\"aggregations\":{},\"query\":{\"match\":{\"name\":{\"query\":\"OpenSearch\"}}},\"terminate_after\":5}"; diff --git a/samples/src/main/java/org/opensearch/client/samples/json/DeserializationBasics.java b/samples/src/main/java/org/opensearch/client/samples/json/DeserializationBasics.java new file mode 100644 index 0000000000..1887a37db9 --- /dev/null +++ b/samples/src/main/java/org/opensearch/client/samples/json/DeserializationBasics.java @@ -0,0 +1,63 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.client.samples.json; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.client.opensearch.OpenSearchClient; +import org.opensearch.client.opensearch.indices.PutIndexTemplateRequest; +import org.opensearch.client.opensearch.indices.PutIndexTemplateResponse; +import org.opensearch.client.opensearch.indices.put_index_template.IndexTemplateMapping; +import org.opensearch.client.samples.SampleClient; +import org.opensearch.client.samples.Search; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + + +public class DeserializationBasics { + private static final Logger LOGGER = LogManager.getLogger(Search.class); + + private static OpenSearchClient client; + + public static void main(String[] args) { + try { + client = SampleClient.create(); + + var version = client.info().version(); + LOGGER.info("Server: {}@{}.", version.distribution(), version.number()); + + final var indexTemplateName = "my-index"; + + // Use Json String/File for storing template. + String stringTemplate = + "{\"mappings\":{\"properties\":{\"age\":{\"type\":\"integer\"}}},\"settings\":{\"number_of_shards\":\"2\",\"number_of_replicas\":\"1\"}}"; + // Create Input Stream for the above json template + InputStream inputStream = new ByteArrayInputStream(stringTemplate.getBytes(StandardCharsets.UTF_8)); + + + // Create Index Template Request for index 'my-index'. + PutIndexTemplateRequest putIndexTemplateRequest = new PutIndexTemplateRequest.Builder() + .name(indexTemplateName) + .template(new IndexTemplateMapping.Builder().withJson(inputStream).build()) // Use the Builder.withJson method to deserialize the inputStream into an instance of the IndexTemplateMapping class. + .build(); + + LOGGER.info("Creating index template {}.", indexTemplateName); + + // Use toJsonString method to log Request and Response string. + LOGGER.debug("Index Template Request: {}.", putIndexTemplateRequest.toJsonString()); + PutIndexTemplateResponse response = client.indices().putIndexTemplate(putIndexTemplateRequest); + LOGGER.info("Index Template Response: {}.", response.toJsonString()); + + } catch (Exception e) { + LOGGER.error("Exception occurred.", e); + } + } +}