From ef1f0f31005f907b2737221e6036b6fb8f91eada Mon Sep 17 00:00:00 2001 From: smf-h <692979649@qq.com> Date: Mon, 29 Jun 2026 13:27:54 +0800 Subject: [PATCH] Allow bulk shard failures without shard id Signed-off-by: smf-h <692979649@qq.com> --- CHANGELOG.md | 1 + .../opensearch/_types/ShardSearchFailure.java | 25 +++++---- .../opensearch/core/BulkResponseTest.java | 52 +++++++++++++++++++ .../transformer/overrides/Overrides.java | 2 + 4 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 java-client/src/test/java/org/opensearch/client/opensearch/core/BulkResponseTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index f85eaecf78..4fc4cd0402 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 +- Allow bulk shard failures without shard ids ([#2023](https://github.com/opensearch-project/opensearch-java/pull/2023)) ## [Unreleased 3.x] ### Added diff --git a/java-client/src/generated/java/org/opensearch/client/opensearch/_types/ShardSearchFailure.java b/java-client/src/generated/java/org/opensearch/client/opensearch/_types/ShardSearchFailure.java index 7ebed2637f..74e4a9b09f 100644 --- a/java-client/src/generated/java/org/opensearch/client/opensearch/_types/ShardSearchFailure.java +++ b/java-client/src/generated/java/org/opensearch/client/opensearch/_types/ShardSearchFailure.java @@ -72,7 +72,8 @@ public class ShardSearchFailure implements PlainJsonSerializable, ToCopyableBuil @Nonnull private final ErrorCause reason; - private final int shard; + @Nullable + private final Integer shard; // --------------------------------------------------------------------------------------------- @@ -80,7 +81,7 @@ private ShardSearchFailure(Builder builder) { this.index = builder.index; this.node = builder.node; this.reason = ApiTypeHelper.requireNonNull(builder.reason, this, "reason"); - this.shard = ApiTypeHelper.requireNonNull(builder.shard, this, "shard"); + this.shard = builder.shard; } public static ShardSearchFailure of(Function> fn) { @@ -118,12 +119,13 @@ public final ErrorCause reason() { } /** - * Required - The shard id where the failure occurred. + * The shard id where the failure occurred. *

* API name: {@code shard} *

*/ - public final int shard() { + @Nullable + public final Integer shard() { return this.shard; } @@ -151,8 +153,10 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { generator.writeKey("reason"); this.reason.serialize(generator, mapper); - generator.writeKey("shard"); - generator.write(this.shard); + if (this.shard != null) { + generator.writeKey("shard"); + generator.write(this.shard); + } } // --------------------------------------------------------------------------------------------- @@ -177,6 +181,7 @@ public static class Builder extends ObjectBuilderBase implements CopyableBuilder @Nullable private String node; private ErrorCause reason; + @Nullable private Integer shard; public Builder() {} @@ -243,13 +248,13 @@ public final Builder reason(Function * API name: {@code shard} *

*/ @Nonnull - public final Builder shard(int value) { + public final Builder shard(@Nullable Integer value) { this.shard = value; return this; } @@ -291,7 +296,7 @@ public int hashCode() { result = 31 * result + Objects.hashCode(this.index); result = 31 * result + Objects.hashCode(this.node); result = 31 * result + this.reason.hashCode(); - result = 31 * result + Integer.hashCode(this.shard); + result = 31 * result + Objects.hashCode(this.shard); return result; } @@ -303,6 +308,6 @@ public boolean equals(Object o) { return Objects.equals(this.index, other.index) && Objects.equals(this.node, other.node) && this.reason.equals(other.reason) - && this.shard == other.shard; + && Objects.equals(this.shard, other.shard); } } diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/core/BulkResponseTest.java b/java-client/src/test/java/org/opensearch/client/opensearch/core/BulkResponseTest.java new file mode 100644 index 0000000000..bf7c708307 --- /dev/null +++ b/java-client/src/test/java/org/opensearch/client/opensearch/core/BulkResponseTest.java @@ -0,0 +1,52 @@ +/* + * 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.opensearch.core; + +import org.junit.Test; +import org.opensearch.client.opensearch._types.ShardSearchFailure; +import org.opensearch.client.opensearch.core.bulk.BulkResponseItem; +import org.opensearch.client.opensearch.model.ModelTestCase; + +public class BulkResponseTest extends ModelTestCase { + + @Test + public void shouldDeserializeBulkResponseShardFailureWithoutShard() { + String json = "{\"took\":1,\"errors\":true,\"items\":[{\"index\":{\"_index\":\"products\",\"status\":500," + + "\"error\":{\"type\":\"illegal_argument_exception\",\"reason\":\"boom\"}," + + "\"_shards\":{\"total\":2,\"successful\":1,\"failed\":1,\"failures\":[{\"index\":\"products\"," + + "\"node\":\"node-1\",\"reason\":{\"type\":\"illegal_argument_exception\",\"reason\":\"boom\"}}]}}}]}"; + + BulkResponse response = fromJson(json, BulkResponse._DESERIALIZER); + + BulkResponseItem item = response.items().get(0); + assertEquals(500, item.status()); + assertNotNull(item.shards()); + ShardSearchFailure failure = item.shards().failures().get(0); + assertEquals("products", failure.index()); + assertNull(failure.shard()); + assertEquals("illegal_argument_exception", failure.reason().type()); + } + + @Test + public void shouldDeserializeBulkResponseShardFailureWithShard() { + String json = "{\"took\":1,\"errors\":true,\"items\":[{\"index\":{\"_index\":\"products\",\"status\":500," + + "\"error\":{\"type\":\"illegal_argument_exception\",\"reason\":\"boom\"}," + + "\"_shards\":{\"total\":2,\"successful\":1,\"failed\":1,\"failures\":[{\"index\":\"products\"," + + "\"node\":\"node-1\",\"shard\":3,\"reason\":{\"type\":\"illegal_argument_exception\",\"reason\":\"boom\"}}]}}}]}"; + + BulkResponse response = fromJson(json, BulkResponse._DESERIALIZER); + + BulkResponseItem item = response.items().get(0); + assertNotNull(item.shards()); + ShardSearchFailure failure = item.shards().failures().get(0); + assertEquals("products", failure.index()); + assertEquals(Integer.valueOf(3), failure.shard()); + assertEquals("illegal_argument_exception", failure.reason().type()); + } +} diff --git a/java-codegen/src/main/java/org/opensearch/client/codegen/transformer/overrides/Overrides.java b/java-codegen/src/main/java/org/opensearch/client/codegen/transformer/overrides/Overrides.java index b41842eda3..cdf1b6c654 100644 --- a/java-codegen/src/main/java/org/opensearch/client/codegen/transformer/overrides/Overrides.java +++ b/java-codegen/src/main/java/org/opensearch/client/codegen/transformer/overrides/Overrides.java @@ -88,6 +88,8 @@ private static JsonPointer schema(String namespace, String name) { .with(schema("_common", "StringifiedVersionNumber"), so -> so.withMappedType(Types.Primitive.Long)) .with(schema("_common", "Void"), so -> so.withMappedType(Types.Primitive.Void)) + .with(schema("_common", "ShardSearchFailure"), so -> so.withProperties(p -> p.with("shard", po -> po.withRequired(false)))) + .with(schema("_common", "ScriptSort"), so -> so.withShouldGenerate(ShouldGenerate.Always)) .with( schema("_common", "SortOptions"),