diff --git a/CHANGELOG.md b/CHANGELOG.md index 52a6e7451a..96e230a766 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ This section is for maintaining a changelog for all breaking changes for the cli ### Dependencies ### Changed +Allow null values in arrays ([#687](https://github.com/opensearch-project/opensearch-java/pull/687)) ### Deprecated diff --git a/java-client/src/main/java/org/opensearch/client/json/JsonpDeserializerBase.java b/java-client/src/main/java/org/opensearch/client/json/JsonpDeserializerBase.java index df405110eb..bc8da85c58 100644 --- a/java-client/src/main/java/org/opensearch/client/json/JsonpDeserializerBase.java +++ b/java-client/src/main/java/org/opensearch/client/json/JsonpDeserializerBase.java @@ -335,8 +335,13 @@ public List deserialize(JsonParser parser, JsonpMapper mapper, Event event) { if (event == Event.START_ARRAY) { List result = new ArrayList<>(); while ((event = parser.next()) != Event.END_ARRAY) { - JsonpUtils.ensureAccepts(itemDeserializer, parser, event); - result.add(itemDeserializer.deserialize(parser, mapper, event)); + // JSON null: add null unless the deserializer can handle it + if (event == Event.VALUE_NULL && !itemDeserializer.accepts(event)) { + result.add(null); + } else { + JsonpUtils.ensureAccepts(itemDeserializer, parser, event); + result.add(itemDeserializer.deserialize(parser, mapper, event)); + } } return result; } else { diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/json/JsonpDeserializerBaseTest.java b/java-client/src/test/java/org/opensearch/client/opensearch/json/JsonpDeserializerBaseTest.java new file mode 100644 index 0000000000..400696f429 --- /dev/null +++ b/java-client/src/test/java/org/opensearch/client/opensearch/json/JsonpDeserializerBaseTest.java @@ -0,0 +1,43 @@ +package org.opensearch.client.opensearch.json; + +import jakarta.json.stream.JsonParser; +import java.io.StringReader; +import java.util.List; +import org.junit.Test; +import org.opensearch.client.json.JsonpDeserializer; +import org.opensearch.client.opensearch._types.FieldValue; +import org.opensearch.client.opensearch.model.ModelTestCase; + +public class JsonpDeserializerBaseTest extends ModelTestCase { + + @Test + public void testNullArrayItem() { + + String json = "[\"a\", null, \"c\"]"; + + // Types that don't accept null events should end up as null values in the list + { + JsonpDeserializer stringDeser = JsonpDeserializer.stringDeserializer(); + assertFalse(stringDeser.accepts(JsonParser.Event.VALUE_NULL)); + + JsonParser parser = mapper.jsonProvider().createParser(new StringReader(json)); + + List stringList = JsonpDeserializer.arrayDeserializer(stringDeser).deserialize(parser, mapper); + assertEquals("a", stringList.get(0)); + assertNull(stringList.get(1)); + assertEquals("c", stringList.get(2)); + } + + // Types that do accept null events should end up as their null representation + { + assertTrue(FieldValue._DESERIALIZER.accepts(JsonParser.Event.VALUE_NULL)); + + JsonParser parser = mapper.jsonProvider().createParser(new StringReader(json)); + List valueList = JsonpDeserializer.arrayDeserializer(FieldValue._DESERIALIZER).deserialize(parser, mapper); + + assertEquals("a", valueList.get(0)._get()); + assertTrue(valueList.get(1).isNull()); + assertEquals("c", valueList.get(2)._get()); + } + } +}