diff --git a/CHANGELOG.md b/CHANGELOG.md index f85eaecf78..75a4cdc859 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Add document lifecycle guide and runnable sample ([#2017](https://github.com/opensearch-project/opensearch-java/pull/2017)) ### Fixed +- Fix `NullPointerException` in `_listAddAll` when server returns JSON `null` for a list field ([#2041](https://github.com/opensearch-project/opensearch-java/pull/2041)) ## [Unreleased 3.x] ### Added diff --git a/java-client/src/generated/java/org/opensearch/client/opensearch/core/search/ShardProfile.java b/java-client/src/generated/java/org/opensearch/client/opensearch/core/search/ShardProfile.java index 8640b1d2d6..15085ab581 100644 --- a/java-client/src/generated/java/org/opensearch/client/opensearch/core/search/ShardProfile.java +++ b/java-client/src/generated/java/org/opensearch/client/opensearch/core/search/ShardProfile.java @@ -64,8 +64,8 @@ public class ShardProfile implements PlainJsonSerializable, ToCopyableBuilder aggregations; - @Nullable - private final FetchProfile fetch; + @Nonnull + private final List fetch; @Nonnull private final String id; @@ -77,7 +77,7 @@ public class ShardProfile implements PlainJsonSerializable, ToCopyableBuilder aggregations() { /** * API name: {@code fetch} */ - @Nullable - public final FetchProfile fetch() { + @Nonnull + public final List fetch() { return this.fetch; } @@ -136,9 +136,13 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { } generator.writeEnd(); - if (this.fetch != null) { + if (ApiTypeHelper.isDefined(this.fetch)) { generator.writeKey("fetch"); - this.fetch.serialize(generator, mapper); + generator.writeStartArray(); + for (FetchProfile item0 : this.fetch) { + item0.serialize(generator, mapper); + } + generator.writeEnd(); } generator.writeKey("id"); @@ -171,7 +175,7 @@ public static Builder builder() { public static class Builder extends ObjectBuilderBase implements CopyableBuilder { private List aggregations; @Nullable - private FetchProfile fetch; + private List fetch; private String id; private List searches; @@ -179,14 +183,14 @@ public Builder() {} private Builder(ShardProfile o) { this.aggregations = _listCopy(o.aggregations); - this.fetch = o.fetch; + this.fetch = _listCopy(o.fetch); this.id = o.id; this.searches = _listCopy(o.searches); } private Builder(Builder o) { this.aggregations = _listCopy(o.aggregations); - this.fetch = o.fetch; + this.fetch = _listCopy(o.fetch); this.id = o.id; this.searches = _listCopy(o.searches); } @@ -237,15 +241,36 @@ public final Builder aggregations(Function + * Adds all elements of list to fetch. + *

+ */ + @Nonnull + public final Builder fetch(List list) { + this.fetch = _listAddAll(this.fetch, list); + return this; + } + + /** + * API name: {@code fetch} + * + *

+ * Adds one or more values to fetch. + *

*/ @Nonnull - public final Builder fetch(@Nullable FetchProfile value) { - this.fetch = value; + public final Builder fetch(FetchProfile value, FetchProfile... values) { + this.fetch = _listAdd(this.fetch, value, values); return this; } /** * API name: {@code fetch} + * + *

+ * Adds a value to fetch using a builder lambda. + *

*/ @Nonnull public final Builder fetch(Function> fn) { @@ -325,7 +350,7 @@ public ShardProfile build() { protected static void setupShardProfileDeserializer(ObjectDeserializer op) { op.add(Builder::aggregations, JsonpDeserializer.arrayDeserializer(AggregationProfile._DESERIALIZER), "aggregations"); - op.add(Builder::fetch, FetchProfile._DESERIALIZER, "fetch"); + op.add(Builder::fetch, JsonpDeserializer.arrayDeserializer(FetchProfile._DESERIALIZER), "fetch"); op.add(Builder::id, JsonpDeserializer.stringDeserializer(), "id"); op.add(Builder::searches, JsonpDeserializer.arrayDeserializer(SearchProfile._DESERIALIZER), "searches"); } diff --git a/java-client/src/main/java/org/opensearch/client/util/ObjectBuilderBase.java b/java-client/src/main/java/org/opensearch/client/util/ObjectBuilderBase.java index e1aa0627c9..524b478148 100644 --- a/java-client/src/main/java/org/opensearch/client/util/ObjectBuilderBase.java +++ b/java-client/src/main/java/org/opensearch/client/util/ObjectBuilderBase.java @@ -95,10 +95,15 @@ protected static List _listAdd(List list, T value, T... values) { /** Add all elements of a list to a (possibly {@code null}) list */ protected static List _listAddAll(List list, List values) { + if (values == null) { + // Server returned JSON null for a list field; treat as empty to avoid NPE. + // See https://github.com/opensearch-project/opensearch-java/issues/1813 + return list; + } if (list == null) { // Keep the original list to avoid an unnecessary copy. // It will be copied if we add more values. - return Objects.requireNonNull(values); + return values; } else { list = _mutableList(list); list.addAll(values); diff --git a/java-codegen/opensearch-openapi.yaml b/java-codegen/opensearch-openapi.yaml index b4829f72a0..468f21a1c0 100644 --- a/java-codegen/opensearch-openapi.yaml +++ b/java-codegen/opensearch-openapi.yaml @@ -52512,7 +52512,9 @@ components: items: $ref: '#/components/schemas/_core.search___SearchProfile' fetch: - $ref: '#/components/schemas/_core.search___FetchProfile' + type: array + items: + $ref: '#/components/schemas/_core.search___FetchProfile' required: - aggregations - id