From f7472d2d3611de324313241a37a20ff0118de4fb Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 30 Aug 2022 13:55:54 -0700 Subject: [PATCH] Enable Locator applications configured and bootstrapped with Spring to be optionally configured with Apache Geode's Cluster Configuration Service. Configuration with Aapche Geode's Cluster Configuration Service is now disabled by default, to be consistent with peer Cache applications. Closes #622. --- .../data/gemfire/LocatorFactoryBean.java | 12 +++ .../config/annotation/LocatorApplication.java | 14 +++ .../LocatorApplicationConfiguration.java | 14 +++ .../gemfire/LocatorFactoryBeanUnitTests.java | 87 +++++++++++-------- ...licationConfigurationIntegrationTests.java | 4 +- 5 files changed, 95 insertions(+), 36 deletions(-) diff --git a/spring-data-geode/src/main/java/org/springframework/data/gemfire/LocatorFactoryBean.java b/spring-data-geode/src/main/java/org/springframework/data/gemfire/LocatorFactoryBean.java index 1edc683c..c89ec9fa 100644 --- a/spring-data-geode/src/main/java/org/springframework/data/gemfire/LocatorFactoryBean.java +++ b/spring-data-geode/src/main/java/org/springframework/data/gemfire/LocatorFactoryBean.java @@ -62,6 +62,7 @@ public class LocatorFactoryBean extends AbstractFactoryBeanSupport impl public static final String LOG_LEVEL_PROPERTY = GemFireProperties.LOG_LEVEL.getName(); private boolean useBeanFactoryLocator = false; + private boolean useClusterConfigurationService = false; private Integer port = DEFAULT_PORT; @@ -148,6 +149,9 @@ public class LocatorFactoryBean extends AbstractFactoryBeanSupport impl gemfireProperties.stringPropertyNames().stream() .forEach(propertyName -> locatorBuilder.set(propertyName, gemfireProperties.getProperty(propertyName))); + locatorBuilder.set(GemFireProperties.USE_CLUSTER_CONFIGURATION.getName(), + String.valueOf(isUseClusterConfigurationService())); + return locatorBuilder; } @@ -293,4 +297,12 @@ public class LocatorFactoryBean extends AbstractFactoryBeanSupport impl public boolean isUseBeanFactoryLocator() { return this.useBeanFactoryLocator; } + + public void setUseClusterConfigurationService(boolean useClusterConfigurationService) { + this.useClusterConfigurationService = useClusterConfigurationService; + } + + public boolean isUseClusterConfigurationService() { + return this.useClusterConfigurationService; + } } diff --git a/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/LocatorApplication.java b/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/LocatorApplication.java index a6862ba1..f4327b3c 100644 --- a/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/LocatorApplication.java +++ b/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/LocatorApplication.java @@ -35,13 +35,16 @@ import org.springframework.data.gemfire.support.GemfireBeanFactoryLocator; * application to become a {@link Locator} based application. * * @author John Blum + * @see java.lang.annotation.Annotation * @see java.lang.annotation.Documented * @see java.lang.annotation.Inherited * @see java.lang.annotation.Retention * @see java.lang.annotation.Target + * @see org.apache.geode.distributed.Locator * @see org.springframework.context.annotation.Configuration * @see org.springframework.context.annotation.Import * @see org.springframework.data.gemfire.config.annotation.LocatorApplicationConfiguration + * @see org.springframework.data.gemfire.support.GemfireBeanFactoryLocator * @since 2.2.0 */ @Target(ElementType.TYPE) @@ -123,4 +126,15 @@ public @interface LocatorApplication { */ boolean useBeanFactoryLocator() default LocatorApplicationConfiguration.DEFAULT_USE_BEAN_FACTORY_LOCATOR; + /** + * Configures whether the Spring-based {@link Locator} will pull configuration metadata from the Apache Geode + * cluster-based, Cluster Configuration Service. + * + * Defaults to {@literal false}. + * + * Use {@literal spring.data.gemfire.locator.use-cluster-configuration} property + * in {@literal application.properties}. + */ + boolean useClusterConfiguration() default LocatorApplicationConfiguration.DEFAULT_USE_CLUSTER_CONFIGURATTION_SERVICE; + } diff --git a/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/LocatorApplicationConfiguration.java b/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/LocatorApplicationConfiguration.java index 5df7f59a..e80f5520 100644 --- a/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/LocatorApplicationConfiguration.java +++ b/spring-data-geode/src/main/java/org/springframework/data/gemfire/config/annotation/LocatorApplicationConfiguration.java @@ -67,6 +67,7 @@ import org.springframework.util.ClassUtils; public class LocatorApplicationConfiguration extends AbstractAnnotationConfigSupport implements ImportAware { public static final boolean DEFAULT_USE_BEAN_FACTORY_LOCATOR = false; + public static final boolean DEFAULT_USE_CLUSTER_CONFIGURATTION_SERVICE = false; public static final int DEFAULT_PORT = 10334; @@ -86,6 +87,7 @@ public class LocatorApplicationConfiguration extends AbstractAnnotationConfigSup Arrays.asList(CacheFactoryBean.class.getName(), ClientCacheFactoryBean.class.getName()); private boolean useBeanFactoryLocator = DEFAULT_USE_BEAN_FACTORY_LOCATOR; + private boolean useClusterConfigurationService = DEFAULT_USE_CLUSTER_CONFIGURATTION_SERVICE; private int port = DEFAULT_PORT; @@ -189,6 +191,9 @@ public class LocatorApplicationConfiguration extends AbstractAnnotationConfigSup setUseBeanFactoryLocator(resolveProperty("use-bean-factory-locator", Boolean.class, locatorApplicationAnnotationAttributes.getBoolean("useBeanFactoryLocator"))); + + setUseClusterConfigurationService(resolveProperty(locatorProperty("use-cluster-configuration"), + Boolean.class, locatorApplicationAnnotationAttributes.getBoolean("useClusterConfiguration"))); } } @@ -205,6 +210,7 @@ public class LocatorApplicationConfiguration extends AbstractAnnotationConfigSup locatorFactoryBean.setName(getName()); locatorFactoryBean.setPort(getPort()); locatorFactoryBean.setUseBeanFactoryLocator(isUseBeanFactoryLocator()); + locatorFactoryBean.setUseClusterConfigurationService(isUseClusterConfigurationService()); return locatorFactoryBean; } @@ -272,4 +278,12 @@ public class LocatorApplicationConfiguration extends AbstractAnnotationConfigSup public void setUseBeanFactoryLocator(boolean useBeanFactoryLocator) { this.useBeanFactoryLocator = useBeanFactoryLocator; } + + public void setUseClusterConfigurationService(boolean useClusterConfigurationService) { + this.useClusterConfigurationService = useClusterConfigurationService; + } + + public boolean isUseClusterConfigurationService() { + return useClusterConfigurationService; + } } diff --git a/spring-data-geode/src/test/java/org/springframework/data/gemfire/LocatorFactoryBeanUnitTests.java b/spring-data-geode/src/test/java/org/springframework/data/gemfire/LocatorFactoryBeanUnitTests.java index ca819f50..33e763a1 100644 --- a/spring-data-geode/src/test/java/org/springframework/data/gemfire/LocatorFactoryBeanUnitTests.java +++ b/spring-data-geode/src/test/java/org/springframework/data/gemfire/LocatorFactoryBeanUnitTests.java @@ -16,6 +16,8 @@ package org.springframework.data.gemfire; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; @@ -26,6 +28,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import java.net.InetAddress; @@ -63,7 +66,6 @@ public class LocatorFactoryBeanUnitTests { @Before public void setup() { - this.locatorFactoryBean = spy(new LocatorFactoryBean()); } @@ -169,9 +171,9 @@ public class LocatorFactoryBeanUnitTests { Properties gemfireProperties = new Properties(); - gemfireProperties.setProperty("name", "TEST"); - gemfireProperties.setProperty("log-level", "config"); - gemfireProperties.setProperty("locators", "localhost[11235],skullbox[12480]"); + gemfireProperties.setProperty(GemFireProperties.NAME.getName(), "TEST"); + gemfireProperties.setProperty(GemFireProperties.LOG_LEVEL.getName(), "config"); + gemfireProperties.setProperty(GemFireProperties.LOCATORS.getName(), "localhost[11235],skullbox[12480]"); LocatorLauncher.Builder locatorBuilderSpy = spy(new LocatorLauncher.Builder()); @@ -181,6 +183,11 @@ public class LocatorFactoryBeanUnitTests { gemfireProperties.stringPropertyNames().forEach(propertyName -> verify(locatorBuilderSpy, times(1)) .set(eq(propertyName), eq(gemfireProperties.getProperty(propertyName)))); + + verify(locatorBuilderSpy, times(1)) + .set(eq(GemFireProperties.USE_CLUSTER_CONFIGURATION.getName()), eq("false")); + + verifyNoMoreInteractions(locatorBuilderSpy); } @Test @@ -195,19 +202,13 @@ public class LocatorFactoryBeanUnitTests { verify(this.locatorFactoryBean, times(1)).getLocator(); } - @Test(expected = IllegalStateException.class) + @Test public void getObjectThrowsIllegalStateException() throws Exception { - try { - this.locatorFactoryBean.getObject(); - } - catch (IllegalStateException expected) { - - assertThat(expected).hasMessage("Locator was not configured and initialized"); - assertThat(expected).hasNoCause(); - - throw expected; - } + assertThatIllegalStateException() + .isThrownBy(() -> this.locatorFactoryBean.getObject()) + .withMessage("Locator was not configured and initialized") + .withNoCause(); } @Test @@ -385,33 +386,49 @@ public class LocatorFactoryBeanUnitTests { assertThat(this.locatorFactoryBean.getPort()).isEqualTo(54321); } - @Test(expected = IllegalArgumentException.class) + @Test public void setPortToOverflowValue() { - try { - this.locatorFactoryBean.setPort(65536); - } - catch (IllegalArgumentException expected) { - - assertThat(expected).hasMessage("Network port [65536] is not valid"); - assertThat(expected).hasNoCause(); - - throw expected; - } + assertThatIllegalArgumentException() + .isThrownBy(() -> this.locatorFactoryBean.setPort(65536)) + .withMessage("Network port [65536] is not valid") + .withNoCause(); } - @Test(expected = IllegalArgumentException.class) + @Test public void setPortToUnderflowValue() { - try { - this.locatorFactoryBean.setPort(-1); - } - catch (IllegalArgumentException expected) { + assertThatIllegalArgumentException() + .isThrownBy(() -> this.locatorFactoryBean.setPort(-1)) + .withMessage("Network port [-1] is not valid") + .withNoCause(); + } - assertThat(expected).hasMessage("Network port [-1] is not valid"); - assertThat(expected).hasNoCause(); + @Test + public void locatorFactoryBeanUseOfBeanFactoryLocator() { - throw expected; - } + assertThat(this.locatorFactoryBean.isUseBeanFactoryLocator()).isFalse(); + + this.locatorFactoryBean.setUseBeanFactoryLocator(true); + + assertThat(this.locatorFactoryBean.isUseBeanFactoryLocator()).isTrue(); + + this.locatorFactoryBean.setUseBeanFactoryLocator(false); + + assertThat(this.locatorFactoryBean.isUseBeanFactoryLocator()).isFalse(); + } + + @Test + public void locatorFactoryBeanUseOfClusterConfigurationService() { + + assertThat(this.locatorFactoryBean.isUseClusterConfigurationService()).isFalse(); + + this.locatorFactoryBean.setUseClusterConfigurationService(true); + + assertThat(this.locatorFactoryBean.isUseClusterConfigurationService()).isTrue(); + + this.locatorFactoryBean.setUseClusterConfigurationService(false); + + assertThat(this.locatorFactoryBean.isUseClusterConfigurationService()).isFalse(); } } diff --git a/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/LocatorApplicationConfigurationIntegrationTests.java b/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/LocatorApplicationConfigurationIntegrationTests.java index 3f5222e0..c58bc3b1 100644 --- a/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/LocatorApplicationConfigurationIntegrationTests.java +++ b/spring-data-geode/src/test/java/org/springframework/data/gemfire/config/annotation/LocatorApplicationConfigurationIntegrationTests.java @@ -67,6 +67,7 @@ public class LocatorApplicationConfigurationIntegrationTests extends Integration assertThat(this.locatorFactoryBean.getName().orElse(null)).isEqualTo("MockLocator"); assertThat(this.locatorFactoryBean.getPort()).isEqualTo(9876); assertThat(this.locatorFactoryBean.isUseBeanFactoryLocator()).isTrue(); + assertThat(this.locatorFactoryBean.isUseClusterConfigurationService()).isTrue(); } @EnableGemFireMockObjects @@ -77,7 +78,8 @@ public class LocatorApplicationConfigurationIntegrationTests extends Integration logLevel = "WARN", name = "MockLocator", port = 9876, - useBeanFactoryLocator = true + useBeanFactoryLocator = true, + useClusterConfiguration = true ) static class TestConfiguration {