From daddaff35cfa6924e25bff485dadd6bcc34249ab Mon Sep 17 00:00:00 2001 From: "opensearch-trigger-bot[bot]" <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com> Date: Wed, 15 Nov 2023 09:09:15 -0500 Subject: [PATCH] Add support for icu_collation_keyword field type (#725) (#728) * add icu collation keyword * add licensing * update changelog * update changelog pr * add support for icu collation options --------- (cherry picked from commit d8d7a3aac83fa8b4f84a92669dfae7018698fcfb) Signed-off-by: bfindlay Signed-off-by: github-actions[bot] Co-authored-by: github-actions[bot] --- CHANGELOG.md | 1 + .../mapping/IcuCollationKeywordProperty.java | 359 ++++++++++++++++++ .../opensearch/_types/mapping/Property.java | 32 ++ .../core/GetMappingsResponseTest.java | 82 ++++ 4 files changed, 474 insertions(+) create mode 100644 java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/IcuCollationKeywordProperty.java create mode 100644 java-client/src/test/java/org/opensearch/client/opensearch/core/GetMappingsResponseTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 5870ce633c..5353ad45fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased 2.x] ### Added +- Added support for icu_collation_keyword type ([#725](https://github.com/opensearch-project/opensearch-java/pull/725)) ### Dependencies diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/IcuCollationKeywordProperty.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/IcuCollationKeywordProperty.java new file mode 100644 index 0000000000..17f3928655 --- /dev/null +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/IcuCollationKeywordProperty.java @@ -0,0 +1,359 @@ +/* + * 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._types.mapping; + +import jakarta.json.stream.JsonGenerator; +import java.util.function.Function; +import javax.annotation.Nullable; +import org.opensearch.client.json.*; +import org.opensearch.client.opensearch._types.analysis.IcuCollationAlternate; +import org.opensearch.client.opensearch._types.analysis.IcuCollationCaseFirst; +import org.opensearch.client.opensearch._types.analysis.IcuCollationDecomposition; +import org.opensearch.client.opensearch._types.analysis.IcuCollationStrength; +import org.opensearch.client.util.ObjectBuilder; + +// typedef: _types.mapping.ICUCollationKeywordProperty + +@JsonpDeserializable +public class IcuCollationKeywordProperty extends DocValuesPropertyBase implements PropertyVariant { + + @Nullable + private final Boolean index; + + @Nullable + private final String nullValue; + + // Collation Options + + @Nullable + private final IcuCollationAlternate alternate; + + @Nullable + private final Boolean caseLevel; + + @Nullable + private final IcuCollationCaseFirst caseFirst; + + @Nullable + private final IcuCollationDecomposition decomposition; + + @Nullable + private final Boolean hiraganaQuaternaryMode; + + @Nullable + private final Boolean numeric; + + @Nullable + private final IcuCollationStrength strength; + + @Nullable + private final String variableTop; + + // --------------------------------------------------------------------------------------------- + + private IcuCollationKeywordProperty(Builder builder) { + super(builder); + this.index = builder.index; + this.nullValue = builder.nullValue; + this.alternate = builder.alternate; + this.caseLevel = builder.caseLevel; + this.caseFirst = builder.caseFirst; + this.decomposition = builder.decomposition; + this.hiraganaQuaternaryMode = builder.hiraganaQuaternaryMode; + this.numeric = builder.numeric; + this.strength = builder.strength; + this.variableTop = builder.variableTop; + } + + public static IcuCollationKeywordProperty of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + @Override + public Property.Kind _propertyKind() { + return Property.Kind.IcuCollationKeyword; + } + + /** + * API name: {@code index} + */ + @Nullable + public final Boolean index() { + return this.index; + } + + /** + * API name: {@code null_value} + */ + @Nullable + public final String nullValue() { + return this.nullValue; + } + + /** + * API name: {@code alternate} + */ + public final IcuCollationAlternate alternate() { + return this.alternate; + } + + /** + * API name: {@code case_level} + */ + public final Boolean caseLevel() { + return this.caseLevel; + } + + /** + * API name: {@code case_first} + */ + public final IcuCollationCaseFirst caseFirst() { + return this.caseFirst; + } + + /** + * API name: {@code decomposition} + */ + public final IcuCollationDecomposition decomposition() { + return this.decomposition; + } + + /** + * API name: {@code hiragana_quaternary_mode} + */ + public final Boolean hiraganaQuaternaryMode() { + return this.hiraganaQuaternaryMode; + } + + /** + * API name: {@code numeric} + */ + public final Boolean numeric() { + return this.numeric; + } + + /** + * API name: {@code strength} + */ + public final IcuCollationStrength strength() { + return this.strength; + } + + /** + * API name: {@code variable_top} + */ + public final String variableTop() { + return this.variableTop; + } + + protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) { + generator.write("type", "icu_collation_keyword"); + super.serializeInternal(generator, mapper); + if (this.index != null) { + generator.writeKey("index"); + generator.write(this.index); + } + if (this.nullValue != null) { + generator.writeKey("null_value"); + generator.write(this.nullValue); + } + if (this.alternate != null) { + generator.writeKey("alternate"); + generator.write(this.alternate.jsonValue()); + } + if (this.caseLevel != null) { + generator.writeKey("case_level"); + generator.write(this.caseLevel); + } + if (this.caseFirst != null) { + generator.writeKey("case_first"); + generator.write(this.caseFirst.jsonValue()); + } + if (this.decomposition != null) { + generator.writeKey("decomposition"); + generator.write(this.decomposition.jsonValue()); + } + if (this.hiraganaQuaternaryMode != null) { + generator.writeKey("hiragana_quaternary_mode"); + generator.write(this.hiraganaQuaternaryMode); + } + if (this.numeric != null) { + generator.writeKey("numeric"); + generator.write(this.numeric); + } + if (this.strength != null) { + generator.writeKey("strength"); + generator.write(this.strength.jsonValue()); + } + if (this.variableTop != null) { + generator.writeKey("variable_top"); + generator.write(this.variableTop); + } + } + + // --------------------------------------------------------------------------------------------- + + /** + * Builder for {@link IcuCollationKeywordProperty}. + */ + + public static class Builder extends DocValuesPropertyBase.AbstractBuilder + implements + ObjectBuilder { + @Nullable + private Boolean index; + + @Nullable + private String nullValue; + + @Nullable + private IcuCollationAlternate alternate; + + @Nullable + private Boolean caseLevel; + + @Nullable + private IcuCollationCaseFirst caseFirst; + + @Nullable + private IcuCollationDecomposition decomposition; + + @Nullable + private Boolean hiraganaQuaternaryMode; + + @Nullable + private Boolean numeric; + + @Nullable + private IcuCollationStrength strength; + + @Nullable + private String variableTop; + + /** + * API name: {@code index} + */ + public final Builder index(@Nullable Boolean value) { + this.index = value; + return this; + } + + /** + * API name: {@code null_value} + */ + public final Builder nullValue(@Nullable String value) { + this.nullValue = value; + return this; + } + + /** + * API name: {@code alternate} + */ + public final Builder alternate(@Nullable IcuCollationAlternate value) { + this.alternate = value; + return this; + } + + /** + * API name: {@code case_level} + */ + public final Builder caseLevel(@Nullable Boolean value) { + this.caseLevel = value; + return this; + } + + /** + * API name: {@code case_first} + */ + public final Builder caseFirst(@Nullable IcuCollationCaseFirst value) { + this.caseFirst = value; + return this; + } + + /** + * API name: {@code decomposition} + */ + public final Builder decomposition(@Nullable IcuCollationDecomposition value) { + this.decomposition = value; + return this; + } + + /** + * API name: {@code hiragana_quaternary_mode} + */ + public final Builder hiraganaQuaternaryMode(@Nullable Boolean value) { + this.hiraganaQuaternaryMode = value; + return this; + } + + /** + * API name: {@code numeric} + */ + public final Builder numeric(@Nullable Boolean value) { + this.numeric = value; + return this; + } + + /** + * API name: {@code strength} + */ + public final Builder strength(@Nullable IcuCollationStrength value) { + this.strength = value; + return this; + } + + /** + * API name: {@code variable_top} + */ + public final Builder variableTop(@Nullable String value) { + this.variableTop = value; + return this; + } + + @Override + protected Builder self() { + return this; + } + + /** + * Builds a {@link IcuCollationKeywordProperty}. + * + * @throws NullPointerException + * if some of the required fields are null. + */ + public IcuCollationKeywordProperty build() { + _checkSingleUse(); + return new IcuCollationKeywordProperty(this); + } + } + + // --------------------------------------------------------------------------------------------- + + /** + * Json deserializer for {@link IcuCollationKeywordProperty} + */ + public static final JsonpDeserializer _DESERIALIZER = ObjectBuilderDeserializer.lazy( + Builder::new, + IcuCollationKeywordProperty::setupIcuCollationKeywordPropertyDeserializer + ); + + protected static void setupIcuCollationKeywordPropertyDeserializer(ObjectDeserializer op) { + DocValuesPropertyBase.setupDocValuesPropertyBaseDeserializer(op); + op.add(Builder::index, JsonpDeserializer.booleanDeserializer(), "index"); + op.add(Builder::nullValue, JsonpDeserializer.stringDeserializer(), "null_value"); + op.add(Builder::alternate, IcuCollationAlternate._DESERIALIZER, "alternate"); + op.add(Builder::caseLevel, JsonpDeserializer.booleanDeserializer(), "case_level"); + op.add(Builder::caseFirst, IcuCollationCaseFirst._DESERIALIZER, "case_first"); + op.add(Builder::decomposition, IcuCollationDecomposition._DESERIALIZER, "decomposition"); + op.add(Builder::hiraganaQuaternaryMode, JsonpDeserializer.booleanDeserializer(), "hiragana_quaternary_mode"); + op.add(Builder::numeric, JsonpDeserializer.booleanDeserializer(), "numeric"); + op.add(Builder::strength, IcuCollationStrength._DESERIALIZER, "strength"); + op.add(Builder::variableTop, JsonpDeserializer.stringDeserializer(), "variable_top"); + } +} diff --git a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java index 827c0551f0..5986748e90 100644 --- a/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java +++ b/java-client/src/main/java/org/opensearch/client/opensearch/_types/mapping/Property.java @@ -98,6 +98,8 @@ public enum Kind implements JsonEnum { Histogram("histogram"), + IcuCollationKeyword("icu_collation_keyword"), + Integer("integer"), IntegerRange("integer_range"), @@ -518,6 +520,23 @@ public HistogramProperty histogram() { return TaggedUnionUtils.get(this, Kind.Histogram); } + /** + * Is this variant instance of kind {@code icu_collation_keyword}? + */ + public boolean isIcuCollationKeyword() { + return _kind == Kind.IcuCollationKeyword; + } + + /** + * Get the {@code icu_collation_keyword} variant value. + * + * @throws IllegalStateException + * if the current variant is not of the {@code icu_collation_keyword} kind. + */ + public IcuCollationKeywordProperty icuCollationKeyword() { + return TaggedUnionUtils.get(this, Kind.IcuCollationKeyword); + } + /** * Is this variant instance of kind {@code integer}? */ @@ -1149,6 +1168,18 @@ public ObjectBuilder histogram(Function icuCollationKeyword(IcuCollationKeywordProperty v) { + this._kind = Kind.IcuCollationKeyword; + this._value = v; + return this; + } + + public ObjectBuilder icuCollationKeyword( + Function> fn + ) { + return this.icuCollationKeyword(fn.apply(new IcuCollationKeywordProperty.Builder()).build()); + } + public ObjectBuilder integer(IntegerNumberProperty v) { this._kind = Kind.Integer; this._value = v; @@ -1433,6 +1464,7 @@ protected static void setupPropertyDeserializer(ObjectDeserializer op) op.add(Builder::geoShape, GeoShapeProperty._DESERIALIZER, "geo_shape"); op.add(Builder::halfFloat, HalfFloatNumberProperty._DESERIALIZER, "half_float"); op.add(Builder::histogram, HistogramProperty._DESERIALIZER, "histogram"); + op.add(Builder::icuCollationKeyword, IcuCollationKeywordProperty._DESERIALIZER, "icu_collation_keyword"); op.add(Builder::integer, IntegerNumberProperty._DESERIALIZER, "integer"); op.add(Builder::integerRange, IntegerRangeProperty._DESERIALIZER, "integer_range"); op.add(Builder::ip, IpProperty._DESERIALIZER, "ip"); diff --git a/java-client/src/test/java/org/opensearch/client/opensearch/core/GetMappingsResponseTest.java b/java-client/src/test/java/org/opensearch/client/opensearch/core/GetMappingsResponseTest.java new file mode 100644 index 0000000000..9f72b6cca0 --- /dev/null +++ b/java-client/src/test/java/org/opensearch/client/opensearch/core/GetMappingsResponseTest.java @@ -0,0 +1,82 @@ +package org.opensearch.client.opensearch.core; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.StringReader; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.junit.Assert; +import org.junit.Test; +import org.opensearch.client.json.JsonpMapper; +import org.opensearch.client.json.jsonb.JsonbJsonpMapper; +import org.opensearch.client.opensearch._types.mapping.IcuCollationKeywordProperty; +import org.opensearch.client.opensearch._types.mapping.Property; +import org.opensearch.client.opensearch.indices.GetTemplateResponse; + +public class GetMappingsResponseTest extends Assert { + + @Test + public void deserialize_IcuCollationKeywordExists_propertyDeserializes() throws JsonProcessingException { + Map mappingTemplate = new HashMap<>(); + Map icuCollationConfig = new HashMap<>(); + icuCollationConfig.put("type", "icu_collation_keyword"); + icuCollationConfig.put("ignore_above", 1); + icuCollationConfig.put("index", true); + icuCollationConfig.put("null_value", "not-null-value"); + icuCollationConfig.put("store", true); + + // Collations + icuCollationConfig.put("alternate", "shifted"); + icuCollationConfig.put("case_level", true); + icuCollationConfig.put("case_first", "lower"); + icuCollationConfig.put("decomposition", "no"); + icuCollationConfig.put("hiragana_quaternary_mode", true); + icuCollationConfig.put("numeric", true); + icuCollationConfig.put("strength", "quaternary"); + icuCollationConfig.put("variable_top", "$"); + + mappingTemplate.put( + "test-index", + Map.of( + "aliases", + Collections.emptyMap(), + "index_patterns", + Collections.singletonList("test-pattern*"), + "mappings", + Map.of("properties", Map.of("icu_test_field", icuCollationConfig)), + "order", + 0, + "settings", + Collections.emptyMap(), + "version", + 1 + ) + ); + final JsonpMapper mapper = new JsonbJsonpMapper(); + final String indexTemplate = new ObjectMapper().writeValueAsString(mappingTemplate); + final var parser = mapper.jsonProvider().createParser(new StringReader(indexTemplate)); + + final GetTemplateResponse response = GetTemplateResponse._DESERIALIZER.deserialize(parser, mapper); + final var template = response.get("test-index"); + final var mappings = template.mappings(); + final var properties = mappings.properties(); + final var property = properties.get("icu_test_field"); + final IcuCollationKeywordProperty icu = property.icuCollationKeyword(); + + assertEquals(property._kind(), Property.Kind.IcuCollationKeyword); + assertTrue(property.isIcuCollationKeyword()); + assertEquals(icu.nullValue(), "not-null-value"); + assertTrue(icu.index()); + assertTrue(icu.store()); + assertEquals((int) icu.ignoreAbove(), 1); + assertEquals(icu.alternate().jsonValue(), "shifted"); + assertTrue(icu.caseLevel()); + assertEquals(icu.caseFirst().jsonValue(), "lower"); + assertEquals(icu.decomposition().jsonValue(), "no"); + assertTrue(icu.hiraganaQuaternaryMode()); + assertTrue(icu.numeric()); + assertEquals(icu.strength().jsonValue(), "quaternary"); + assertEquals(icu.variableTop(), "$"); + } +}