From acaa449688cc3da657cd1fb7d78ca7886569398b Mon Sep 17 00:00:00 2001 From: John Blum Date: Fri, 20 Aug 2021 11:04:17 -0700 Subject: [PATCH] Change default Index type from HASH to FUNCTIONAL (Range). Resolves gh-531. --- .../data/gemfire/IndexType.java | 93 +++++++++++-------- .../gemfire/mapping/annotation/Indexed.java | 5 +- .../EnableIndexingConfigurationUnitTests.java | 32 ++++--- ...IndexingConfigurationIntegrationTests.java | 13 ++- .../test/entities/PartitionRegionEntity.java | 4 +- 5 files changed, 82 insertions(+), 65 deletions(-) diff --git a/spring-data-geode/src/main/java/org/springframework/data/gemfire/IndexType.java b/spring-data-geode/src/main/java/org/springframework/data/gemfire/IndexType.java index 56627c43..9a3120a4 100644 --- a/spring-data-geode/src/main/java/org/springframework/data/gemfire/IndexType.java +++ b/spring-data-geode/src/main/java/org/springframework/data/gemfire/IndexType.java @@ -13,11 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.gemfire; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + /** - * The IndexType class is an enumerated type of GemFire Index Types. + * {@link IndexType} is an enumerated type of Apache Geode {@link org.apache.geode.cache.query.IndexType Index Types}. + * + * NOTE: The Apache Geode {@link org.apache.geode.cache.query.IndexType} enum has been deprecated, therefore the SDG + * {@link IndexType} exists to replace it. * * @author John Blum * @see org.apache.geode.cache.query.IndexType @@ -31,58 +37,68 @@ public enum IndexType { PRIMARY_KEY(org.apache.geode.cache.query.IndexType.PRIMARY_KEY), KEY(org.apache.geode.cache.query.IndexType.PRIMARY_KEY); + public static final IndexType DEFAULT = IndexType.FUNCTIONAL; + private final org.apache.geode.cache.query.IndexType gemfireIndexType; /** - * Constructs an instance of the IndexType enum initialized with the given GemFire IndexType. + * Constructs a new instance of the {@link IndexType} enum initialized with the given Apache Geode + * {@link org.apache.geode.cache.query.IndexType}. * - * @param gemfireIndexType the corresponding GemFire IndexType + * @param gemfireIndexType an Apache Geode {@link org.apache.geode.cache.query.IndexType}. + * @throws IllegalArgumentException if the Apache Geode {@link org.apache.geode.cache.query.IndexType} + * is {@literal null}. * @see org.apache.geode.cache.query.IndexType */ - IndexType(final org.apache.geode.cache.query.IndexType gemfireIndexType) { + IndexType(@NonNull org.apache.geode.cache.query.IndexType gemfireIndexType) { + + Assert.notNull(gemfireIndexType, "The Apache Geode IndexType must not be null"); + this.gemfireIndexType = gemfireIndexType; } /** - * Null-safe operation to determine if the IndexType is a "FUNCTIONAL" Index. + * Null-safe operation to determine if the given {@link IndexType} is a {@literal FUNCTIONAL} Index. * - * @param indexType the IndexType to evaluate. - * @return a boolean value indicating whether the IndexType is a "FUNCTIONAL" Index. + * @param indexType {@link IndexType} to evaluate. + * @return a boolean value indicating whether the given {@link IndexType} is a {@literal FUNCTIONAL} Index. * @see #isFunctional() */ - public static boolean isFunctional(IndexType indexType) { - return (indexType != null && indexType.isFunctional()); + public static boolean isFunctional(@Nullable IndexType indexType) { + return indexType != null && indexType.isFunctional(); } /** - * Null-safe operation to determine if the IndexType is a "HASH" Index. + * Null-safe operation to determine if the given {@link IndexType} is a {@literal HASH} Index. * - * @param indexType the IndexType to evaluate. - * @return a boolean value indicating whether the IndexType is a "HASH" Index. + * @param indexType {@link IndexType} to evaluate. + * @return a boolean value indicating whether the given {@link IndexType} is a {@literal HASH} Index. * @see #isHash() */ public static boolean isHash(IndexType indexType) { - return (indexType != null && indexType.isHash()); + return indexType != null && indexType.isHash(); } /** - * Null-safe operation to determine if the IndexType is a "KEY" Index. + * Null-safe operation to determine if the given {@link IndexType} is a {@literal KEY} Index. * - * @param indexType the IndexType to evaluate. - * @return a boolean value indicating whether the IndexType is a "KEY" Index. - * @see #isFunctional() + * @param indexType {@link IndexType} to evaluate. + * @return a boolean value indicating whether the given {@link IndexType} is a {@literal KEY} Index. + * @see #isKey() */ public static boolean isKey(IndexType indexType) { - return (indexType != null && indexType.isKey()); + return indexType != null && indexType.isKey(); } /** - * Returns an IndexType given the corresponding GemFire IndexType or null if no SDG IndexType - * corresponds to the GemFire IndexType. + * Returns an {@link IndexType} given the corresponding Apache Geode {@link org.apache.geode.cache.query.IndexType} + * or {@literal null} if no SDG {@link IndexType} corresponds to the given Apache Geode + * {@link org.apache.geode.cache.query.IndexType}. * - * @param gemfireIndexType the GemFire IndexType. - * @return a IndexType matching the GemFire IndexType or null if the GemFire IndexType does not match - * any IndexType in this enumeration. + * @param gemfireIndexType Apache Geode {@link org.apache.geode.cache.query.IndexType}. + * @return an {@link IndexType} matching the Apache Geode {@link org.apache.geode.cache.query.IndexType} + * or {@literal null} if the Apache Geode {@link org.apache.geode.cache.query.IndexType} does not match + * any {@literal IndexType} in this enumeration. * @see org.apache.geode.cache.query.IndexType */ public static IndexType valueOf(org.apache.geode.cache.query.IndexType gemfireIndexType) { @@ -97,10 +113,10 @@ public enum IndexType { } /** - * Returns an IndexType matching the given String. + * Return an {@link IndexType} matching the given {@link String}. * - * @param value the String value describing the matching IndexType. - * @return an IndexType matching the given String. + * @param value {@link String} value describing {@link IndexType} to match. + * @return an {@link IndexType} matching the given {@link String}. * @see java.lang.String#equalsIgnoreCase(String) */ public static IndexType valueOfIgnoreCase(String value) { @@ -115,39 +131,40 @@ public enum IndexType { } /** - * Gets the matching GemFire IndexType for this IndexType enumerated value. + * Gets the matching Apache Geode {@link org.apache.geode.cache.query.IndexType} for this {@link IndexType} + * enumerated value. * - * @return the matching GemFire IndexType. + * @return the matching Apache Geode {@link org.apache.geode.cache.query.IndexType}. * @see org.apache.geode.cache.query.IndexType */ - public org.apache.geode.cache.query.IndexType getGemfireIndexType() { - return gemfireIndexType; + public @NonNull org.apache.geode.cache.query.IndexType getGemfireIndexType() { + return this.gemfireIndexType; } /** - * Determines whether this IndexType is "FUNCTIONAL". + * Determines whether this {@link IndexType} is a {@literal FUNCTIONAL} Index. * - * @return a boolean value indicating whether this IndexType is "FUNCTIONAL". + * @return a boolean value indicating whether this {@link IndexType} is a {@literal FUNCTIONAL} Index. */ public boolean isFunctional() { return this.equals(FUNCTIONAL); } /** - * Determines whether this IndexType is a "HASH" Index. + * Determines whether this {@link IndexType} is a {@literal HASH} Index. * - * @return a boolean value indicating whether this IndexType is a "HASH" Index. + * @return a boolean value indicating whether this {@literal IndexType} is a {@literal HASH} Index. */ public boolean isHash() { return this.equals(HASH); } /** - * Determines whether this IndexType is a "KEY" Index. + * Determines whether this {@literal IndexType} is a {@literal KEY} Index. * - * @return a boolean value indicating whether this IndexType is a "KEY" Index. + * @return a boolean value indicating whether this {@link IndexType} is a {@literal KEY} Index. */ public boolean isKey() { - return (this.equals(KEY) || this.equals(PRIMARY_KEY)); + return this.equals(KEY) || this.equals(PRIMARY_KEY); } } diff --git a/spring-data-geode/src/main/java/org/springframework/data/gemfire/mapping/annotation/Indexed.java b/spring-data-geode/src/main/java/org/springframework/data/gemfire/mapping/annotation/Indexed.java index 58b587c1..bf7aaa8f 100644 --- a/spring-data-geode/src/main/java/org/springframework/data/gemfire/mapping/annotation/Indexed.java +++ b/spring-data-geode/src/main/java/org/springframework/data/gemfire/mapping/annotation/Indexed.java @@ -14,7 +14,6 @@ * limitations under the License. * */ - package org.springframework.data.gemfire.mapping.annotation; import java.lang.annotation.Documented; @@ -67,7 +66,7 @@ public @interface Indexed { String expression() default ""; /** - * The GemFire/Geode {@link org.apache.geode.cache.Region} on which the Index is created. + * The Apache Geode {@link org.apache.geode.cache.Region} on which the {@link Index} is created. */ String from() default ""; @@ -76,6 +75,6 @@ public @interface Indexed { * * Defaults to {@link IndexType#HASH}. */ - IndexType type() default IndexType.HASH; + IndexType type() default IndexType.FUNCTIONAL; } diff --git a/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableIndexingConfigurationUnitTests.java b/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableIndexingConfigurationUnitTests.java index e188d5bd..0c135199 100644 --- a/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableIndexingConfigurationUnitTests.java +++ b/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableIndexingConfigurationUnitTests.java @@ -68,6 +68,8 @@ import org.springframework.data.gemfire.config.annotation.test.entities.GenericR import org.springframework.data.gemfire.config.annotation.test.entities.LocalRegionEntity; import org.springframework.data.gemfire.config.annotation.test.entities.NonEntity; import org.springframework.data.gemfire.config.annotation.test.entities.ReplicateRegionEntity; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; /** * Unit Tests for the {@link EnableIndexing} and {@link IndexConfiguration} class. @@ -95,19 +97,11 @@ public class EnableIndexingConfigurationUnitTests { private static final Set indexes = Collections.synchronizedSet(new HashSet<>()); - private ConfigurableApplicationContext applicationContext; - - @After - public void tearDown() { - Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close); - indexes.clear(); - } - - private static String[] asArray(List list) { + private static @NonNull String[] asArray(@NonNull List list) { return list.toArray(new String[0]); } - private static String[] toStringArray(Object[] array) { + private static @NonNull String[] toStringArray(@NonNull Object[] array) { String[] stringArray = new String[array.length]; @@ -120,8 +114,7 @@ public class EnableIndexingConfigurationUnitTests { return stringArray; } - /* (non-Javadoc) */ - private static Index findIndexByName(String indexName) { + private static @Nullable Index findIndexByName(@Nullable String indexName) { for (Index index : indexes) { if (index.getName().equalsIgnoreCase(indexName)) { @@ -132,7 +125,17 @@ public class EnableIndexingConfigurationUnitTests { return null; } - /* (non-Javadoc) */ + private ConfigurableApplicationContext applicationContext; + + @After + public void tearDown() { + + Optional.ofNullable(this.applicationContext) + .ifPresent(ConfigurableApplicationContext::close); + + indexes.clear(); + } + private void assertLuceneIndex(LuceneIndex index, String name, String regionPath, String... fields) { assertThat(index).isNotNull(); @@ -142,7 +145,6 @@ public class EnableIndexingConfigurationUnitTests { assertThat(index.getFieldNames()).contains(fields); } - /* (non-Javadoc) */ private void assertOqlIndex(Index index, String name, String expression, String from, IndexType indexType) { assertThat(index).isNotNull(); @@ -152,7 +154,6 @@ public class EnableIndexingConfigurationUnitTests { assertThat(index.getType()).isEqualTo(indexType.getGemfireIndexType()); } - /* (non-Javadoc) */ private ConfigurableApplicationContext newApplicationContext(Class... annotatedClasses) { ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(annotatedClasses); @@ -240,6 +241,7 @@ public class EnableIndexingConfigurationUnitTests { return mockQueryService(mockRegionFactory(mock(Cache.class, "MockGemFireCache"))); } + @SuppressWarnings("deprecation") Cache mockQueryService(Cache mockCache) throws Exception { QueryService mockQueryService = mock(QueryService.class); diff --git a/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableOqlIndexingConfigurationIntegrationTests.java b/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableOqlIndexingConfigurationIntegrationTests.java index 2bb814c2..44c3770c 100644 --- a/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableOqlIndexingConfigurationIntegrationTests.java +++ b/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/EnableOqlIndexingConfigurationIntegrationTests.java @@ -13,21 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.gemfire.config.annotation; import static org.assertj.core.api.Assertions.assertThat; import javax.annotation.Resource; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.Region; import org.apache.geode.cache.client.ClientRegionShortcut; import org.apache.geode.cache.query.Index; -import org.junit.Test; -import org.junit.runner.RunWith; - import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.FilterType; import org.springframework.data.gemfire.GemfireUtils; @@ -63,7 +62,7 @@ public class EnableOqlIndexingConfigurationIntegrationTests { @Resource(name = "PeopleIdKeyIdx") private Index personIdKeyIndex; - @Resource(name = "PeopleLastNameHashIdx") + @Resource(name = "PeopleLastNameFunctionalIdx") private Index personLastNameHashIndex; @Test @@ -92,8 +91,8 @@ public class EnableOqlIndexingConfigurationIntegrationTests { public void idKeyIndexAndLastNameHashIndexAreSetupCorrectly() { assertIndex(this.personIdKeyIndex, "PeopleIdKeyIdx", "id", "/People", IndexType.KEY); - assertIndex(this.personLastNameHashIndex, "PeopleLastNameHashIdx", - "lastName", "/People", IndexType.HASH); + assertIndex(this.personLastNameHashIndex, "PeopleLastNameFunctionalIdx", + "lastName", "/People", IndexType.FUNCTIONAL); } @ClientCacheApplication(logLevel = "none") diff --git a/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/test/entities/PartitionRegionEntity.java b/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/test/entities/PartitionRegionEntity.java index 5934dad1..a4bb88e1 100644 --- a/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/test/entities/PartitionRegionEntity.java +++ b/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/test/entities/PartitionRegionEntity.java @@ -42,10 +42,10 @@ public class PartitionRegionEntity { @Id private Long id; - @Indexed(expression = "first_name", from = "/LoyalCustomers", type = IndexType.FUNCTIONAL) + @Indexed(expression = "first_name", from = "/LoyalCustomers") private String firstName; - @Indexed(name = "LastNameIdx", expression = "surname") + @Indexed(name = "LastNameIdx", expression = "surname", type = IndexType.HASH) private String lastName; @LuceneIndexed("TitleLuceneIdx")