From 2a447e392035005e4e9e360d1b2ea9fb8e5d886b Mon Sep 17 00:00:00 2001 From: MikePieperSer <41434171+MikePieperSer@users.noreply.github.com> Date: Tue, 3 Oct 2023 16:49:34 +0200 Subject: [PATCH] Fixed GetFieldMappingResponse. (#641) * Fixed GetFieldMappingResponse. Signed-off-by: pieper * Add Changelog. Signed-off-by: pieper * Changelog fix. Signed-off-by: pieper * Tabs vs. spaces fix. Signed-off-by: pieper --------- Signed-off-by: pieper Signed-off-by: Vacha Shah --- CHANGELOG.md | 1 + .../_types/mapping/FieldMapping.java | 27 ------- .../get_field_mapping/TypeFieldMappings.java | 47 ++++++++--- .../opensearch/experiments/ParsingTests.java | 78 ++++++++++++++++++- 4 files changed, 115 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 740f639b0c..deaab93a56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - [BUG] JarHell caused by latest software.amazon.awssdk 2.20.141 ([#616](https://github.com/opensearch-project/opensearch-java/pull/616)) - Don't over-allocate in HeapBufferedAsyncEntityConsumer in order to consume the response ([#620](https://github.com/opensearch-project/opensearch-java/pull/620)) - Fixed CVE-2976 + added CVE checker ([#624](https://github.com/opensearch-project/opensearch-java/pull/624)) +- Fix parsing of GetFieldMappingResponse ([#641](https://github.com/opensearch-project/opensearch-java/pull/641)) ### Security diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FieldMapping.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FieldMapping.java index 3ee5bbdf79..7c0b75828a 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FieldMapping.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/FieldMapping.java @@ -50,9 +50,6 @@ @JsonpDeserializable public class FieldMapping implements JsonpSerializable { - // Single key dictionary - private final String field; - private final String fullName; private final Map mapping; @@ -61,8 +58,6 @@ public class FieldMapping implements JsonpSerializable { private FieldMapping(Builder builder) { - this.field = ApiTypeHelper.requireNonNull(builder.field, this, "field"); - this.fullName = ApiTypeHelper.requireNonNull(builder.fullName, this, "fullName"); this.mapping = ApiTypeHelper.unmodifiableRequired(builder.mapping, this, "mapping"); @@ -72,13 +67,6 @@ public static FieldMapping of(Function> fn) return fn.apply(new Builder()).build(); } - /** - * Required - The target field - */ - public final String field() { - return this.field; - } - /** * Required - API name: {@code full_name} */ @@ -103,8 +91,6 @@ public void serialize(JsonGenerator generator, JsonpMapper mapper) { } protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { - generator.writeStartObject(this.field); - generator.writeKey("full_name"); generator.write(this.fullName); @@ -120,8 +106,6 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { } - generator.writeEnd(); - } // --------------------------------------------------------------------------------------------- @@ -131,15 +115,6 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { */ public static class Builder extends ObjectBuilderBase implements ObjectBuilder { - private String field; - - /** - * Required - The target field - */ - public final Builder field(String value) { - this.field = value; - return this; - } private String fullName; @@ -208,8 +183,6 @@ protected static void setupFieldMappingDeserializer(ObjectDeserializer mappings; // --------------------------------------------------------------------------------------------- private TypeFieldMappings(Builder builder) { - this.mappings = ApiTypeHelper.requireNonNull(builder.mappings, this, "mappings"); + this.mappings = ApiTypeHelper.unmodifiableRequired(builder.mappings, this, "mappings"); } @@ -68,7 +71,7 @@ public static TypeFieldMappings of(Function mappings() { return this.mappings; } @@ -84,7 +87,13 @@ public void serialize(JsonGenerator generator, JsonpMapper mapper) { protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { generator.writeKey("mappings"); - this.mappings.serialize(generator, mapper); + generator.writeStartObject(); + for (Map.Entry item0 : this.mappings.entrySet()) { + generator.writeKey(item0.getKey()); + item0.getValue().serialize(generator, mapper); + + } + generator.writeEnd(); } @@ -95,21 +104,39 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { */ public static class Builder extends ObjectBuilderBase implements ObjectBuilder { - private FieldMapping mappings; + private Map mappings; /** * Required - API name: {@code mappings} */ - public final Builder mappings(FieldMapping value) { + public Builder mappings(Map value) { this.mappings = value; return this; } /** - * Required - API name: {@code mappings} + * Add a key/value to {@link #mappings(Map)}, creating the map if needed. + */ + public Builder putMappings(String key, FieldMapping value) { + if (this.mappings == null) { + this.mappings = new HashMap<>(); + } + this.mappings.put(key, value); + return this; + } + + /** + * Set {@link #mappings(Map)} to a singleton map. + */ + public Builder mappings(String key, Function> fn) { + return this.mappings(Collections.singletonMap(key, fn.apply(new FieldMapping.Builder()).build())); + } + + /** + * Add a key/value to {@link #mappings(Map)}, creating the map if needed. */ - public final Builder mappings(Function> fn) { - return this.mappings(fn.apply(new FieldMapping.Builder()).build()); + public Builder putMappings(String key, Function> fn) { + return this.putMappings(key, fn.apply(new FieldMapping.Builder()).build()); } /** @@ -135,7 +162,7 @@ public TypeFieldMappings build() { protected static void setupTypeFieldMappingsDeserializer(ObjectDeserializer op) { - op.add(Builder::mappings, FieldMapping._DESERIALIZER, "mappings"); + op.add(Builder::mappings, JsonpDeserializer.stringMapDeserializer(FieldMapping._DESERIALIZER), "mappings"); } diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/experiments/ParsingTests.java b/java-client/src/test/java/org/opensearch/client/opensearch/experiments/ParsingTests.java index ccb3e4b5d3..026fe79bf1 100644 --- a/java-client/src/test/java/org/opensearch/client/opensearch/experiments/ParsingTests.java +++ b/java-client/src/test/java/org/opensearch/client/opensearch/experiments/ParsingTests.java @@ -33,17 +33,23 @@ package org.opensearch.client.opensearch.experiments; import java.util.List; - +import java.util.Map; import org.junit.Test; import org.opensearch.client.opensearch._types.Time; import org.opensearch.client.opensearch._types.analysis.Analyzer; import org.opensearch.client.opensearch._types.analysis.TokenFilterDefinition; import org.opensearch.client.opensearch._types.analysis.TokenizerBuilders; import org.opensearch.client.opensearch._types.analysis.TokenizerDefinition; +import org.opensearch.client.opensearch._types.mapping.FieldMapping; +import org.opensearch.client.opensearch._types.mapping.Property; +import org.opensearch.client.opensearch._types.mapping.TermVectorOption; +import org.opensearch.client.opensearch._types.mapping.TextProperty; import org.opensearch.client.opensearch.experiments.api.FooRequest; +import org.opensearch.client.opensearch.indices.GetFieldMappingResponse; import org.opensearch.client.opensearch.indices.IndexSettings; import org.opensearch.client.opensearch.indices.IndexSettingsMapping; import org.opensearch.client.opensearch.indices.Translog; +import org.opensearch.client.opensearch.indices.get_field_mapping.TypeFieldMappings; import org.opensearch.client.opensearch.model.ModelTestCase; public class ParsingTests extends ModelTestCase { @@ -173,4 +179,74 @@ public void testCjk_Analyzer() { assertEquals(analyzer.cjk().stopwords(), analyzer2.cjk().stopwords()); assertEquals(analyzer.cjk().stopwordsPath(), analyzer2.cjk().stopwordsPath()); } + + @Test + public void testFieldMappingResponse() { + final String indexName = "indexName"; + final String field1Name = "field1"; + final String field1Analyzer = "my_analyzer"; + final FieldMapping field1 = FieldMapping.of(fmb -> fmb + .fullName(field1Name) + .mapping(field1Name, pb -> pb + .text(tpb -> tpb + .store(true) + .termVector(TermVectorOption.WithPositionsOffsets) + .analyzer(field1Analyzer) + .positionIncrementGap(10)) + ) + ); + final String field3Name = "field3"; + // Build aFieldMappingResponse with several fields + final GetFieldMappingResponse response = GetFieldMappingResponse.of(b -> b + .putResult(indexName, TypeFieldMappings.of(tfmb -> tfmb + .putMappings(field1Name, field1) + .putMappings("field2", fmb -> fmb + .fullName("field2") + .mapping("field2", pb -> pb + .text(tpb -> tpb + .store(true) + .termVector(TermVectorOption.WithPositionsOffsets) + .analyzer("another_analyzer") + .positionIncrementGap(10)) + ) + ) + .putMappings(field3Name, fmb -> fmb + .fullName(field3Name) + .mapping(field3Name, pb -> pb + .text(tpb -> tpb + .store(true) + .termVector(TermVectorOption.WithPositionsOffsets) + .analyzer("this_analyzer") + .positionIncrementGap(10)) + ) + ) + ) + ) + ); + String str = toJson(response); + assertEquals("{\"indexName\":{\"mappings\":{\"field1\":{\"full_name\":\"field1\",\"mapping\"" + +":{\"field1\":{\"type\":\"text\",\"store\":true,\"analyzer\":\"my_analyzer\"," + + "\"position_increment_gap\":10,\"term_vector\":\"with_positions_offsets\"}}}," + +"\"field3\":{\"full_name\":\"field3\",\"mapping\":{\"field3\":{\"type\":\"text\",\"store\":true," + + "\"analyzer\":\"this_analyzer\",\"position_increment_gap\":10,\"term_vector\":\"with_positions_offsets\"}}}," + +"\"field2\":{\"full_name\":\"field2\",\"mapping\":{\"field2\":{\"type\":\"text\",\"store\":true," + +"\"analyzer\":\"another_analyzer\",\"position_increment_gap\":10,\"term_vector\":\"with_positions_offsets\"}}}}}}", str); + + final GetFieldMappingResponse response2 = fromJson(str, GetFieldMappingResponse._DESERIALIZER); + final TypeFieldMappings typeFieldMappings = response2.get(indexName); + assertNotNull(typeFieldMappings); + final Map mappings = typeFieldMappings.mappings(); + assertFalse(mappings.isEmpty()); + final FieldMapping field1_des = mappings.get(field1Name); + assertNotNull(field1_des); + assertEquals(field1Name, field1_des.fullName()); + final Property field1Prop = field1_des.mapping().get(field1Name); + assertNotNull(field1Prop); + final TextProperty textProperty = field1Prop.text(); + assertNotNull(textProperty); + assertEquals(field1Analyzer, textProperty.analyzer()); + + assertNotNull(mappings.get(field3Name)); + } + }