DATAGEODE-13 - Test @EnablePool annotation properties configuration.

This commit is contained in:
John Blum
2017-07-18 18:28:42 -07:00
parent f85f15fee9
commit e016c6fc4b
3 changed files with 341 additions and 4 deletions

View File

@@ -110,6 +110,8 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport<Pool> implements
private PoolConfigurer compositePoolConfigurer = (beanName, bean) ->
nullSafeCollection(poolConfigurers).forEach(poolConfigurer -> poolConfigurer.configure(beanName, bean));
private PoolFactoryInitializer poolFactoryInitializer;
private String name;
private String serverGroup = PoolFactory.DEFAULT_SERVER_GROUP;
@@ -232,7 +234,7 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport<Pool> implements
eagerlyInitializeClientCacheIfNotPresent();
PoolFactory poolFactory = configure(createPoolFactory());
PoolFactory poolFactory = configure(initialize(createPoolFactory()));
this.pool = create(poolFactory, getName());
@@ -317,6 +319,20 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport<Pool> implements
return poolFactory;
}
/**
* Initializes the given {@link PoolFactory} with any configured {@link PoolFactoryInitializer}.
*
* @param poolFactory {@link PoolFactory} to initialize.
* @return the initialized {@link PoolFactory}.
* @see org.apache.geode.cache.client.PoolFactory
*/
protected PoolFactory initialize(PoolFactory poolFactory) {
return Optional.ofNullable(this.poolFactoryInitializer)
.map(initializer -> initializer.initialize(poolFactory))
.orElse(poolFactory);
}
/**
* Creates a {@link Pool} with the given {@link String name} using the provided {@link PoolFactory}.
*
@@ -620,6 +636,18 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport<Pool> implements
this.poolConfigurers = Optional.ofNullable(poolConfigurers).orElseGet(Collections::emptyList);
}
/**
* Sets the {@link PoolFactoryInitializer} to initialize the {@link PoolFactory} used by
* this {@link PoolFactoryBean} to create a {@link Pool}.
*
* @param poolFactoryInitializer {@link PoolFactoryInitializer} user provided callback interface invoked
* by this {@link PoolFactoryBean} to initialize the {@link PoolFactory} constructed to create the {@link Pool}.
* @see org.springframework.data.gemfire.client.PoolFactoryBean.PoolFactoryInitializer
*/
public void setPoolFactoryInitializer(PoolFactoryInitializer poolFactoryInitializer) {
this.poolFactoryInitializer = poolFactoryInitializer;
}
/* (non-Javadoc) */
public void setPrSingleHopEnabled(boolean prSingleHopEnabled) {
this.prSingleHopEnabled = prSingleHopEnabled;
@@ -704,4 +732,22 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport<Pool> implements
*/
public final void setServersConfiguration(Object serversConfiguration) {
}
/**
* Callback interface to initialize the {@link PoolFactory} used by this {@link PoolFactoryBean}
* to create a {@link Pool} by providing additional or alternative configuration for the factory.
*
* @see org.apache.geode.cache.client.PoolFactory
*/
public interface PoolFactoryInitializer {
/**
* Initializes the given {@link PoolFactory}.
*
* @param poolFactory {@link PoolFactory} to initialize.
* @return the given {@link PoolFactory}.
* @see org.apache.geode.cache.client.PoolFactory
*/
PoolFactory initialize(PoolFactory poolFactory);
}
}

View File

@@ -0,0 +1,259 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* 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 java.net.InetSocketAddress;
import java.util.Optional;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.Pool;
import org.apache.geode.cache.client.PoolFactory;
import org.junit.After;
import org.junit.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMocking;
import org.springframework.mock.env.MockPropertySource;
/**
* The PoolPropertiesIntegrationTests class...
*
* @author John Blum
* @since 1.0.0
*/
public class PoolPropertiesIntegrationTests {
private ConfigurableApplicationContext applicationContext;
@After
public void tearDown() {
Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close);
}
private ConfigurableApplicationContext newApplicationContext(PropertySource<?> testPropertySource,
Class<?>... annotatedClasses) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();
propertySources.addFirst(testPropertySource);
applicationContext.registerShutdownHook();
applicationContext.register(annotatedClasses);
applicationContext.refresh();
return applicationContext;
}
private void assertPool(Pool pool, int freeConnectionTimeout, long idleTimeout, int loadConditioningInterval,
int maxConnections, int minConnections, boolean multiUserAuthentication, String name, long pingInterval,
boolean prSinglehopEnabled, int readTimeout, int retryAttempts, String serverGroup, int socketBufferSize,
int statisticInterval, int subscriptionAckInterval, boolean subscriptionEnabled,
int subscriptionMessageTrackingTimeout, int subscriptionRedundancy, boolean threadLocalConnections) {
assertThat(pool).isNotNull();
assertThat(pool.getFreeConnectionTimeout()).isEqualTo(freeConnectionTimeout);
assertThat(pool.getIdleTimeout()).isEqualTo(idleTimeout);
assertThat(pool.getLoadConditioningInterval()).isEqualTo(loadConditioningInterval);
assertThat(pool.getMaxConnections()).isEqualTo(maxConnections);
assertThat(pool.getMinConnections()).isEqualTo(minConnections);
assertThat(pool.getMultiuserAuthentication()).isEqualTo(multiUserAuthentication);
assertThat(pool.getName()).isEqualTo(name);
assertThat(pool.getPingInterval()).isEqualTo(pingInterval);
assertThat(pool.getPRSingleHopEnabled()).isEqualTo(prSinglehopEnabled);
assertThat(pool.getReadTimeout()).isEqualTo(readTimeout);
assertThat(pool.getRetryAttempts()).isEqualTo(retryAttempts);
assertThat(pool.getServerGroup()).isEqualTo(serverGroup);
assertThat(pool.getSocketBufferSize()).isEqualTo(socketBufferSize);
assertThat(pool.getStatisticInterval()).isEqualTo(statisticInterval);
assertThat(pool.getSubscriptionAckInterval()).isEqualTo(subscriptionAckInterval);
assertThat(pool.getSubscriptionEnabled()).isEqualTo(subscriptionEnabled);
assertThat(pool.getSubscriptionMessageTrackingTimeout()).isEqualTo(subscriptionMessageTrackingTimeout);
assertThat(pool.getSubscriptionRedundancy()).isEqualTo(subscriptionRedundancy);
assertThat(pool.getThreadLocalConnections()).isEqualTo(threadLocalConnections);
}
@Test
public void poolConfiguration() {
MockPropertySource testPropertySource = new MockPropertySource()
.withProperty("spring.data.gemfire.pool.free-connection-timeout", 5000)
.withProperty("spring.data.gemfire.pool.locators", "skullbox[11235]")
.withProperty("spring.data.gemfire.pool.max-connections", 500)
.withProperty("spring.data.gemfire.pool.min-connections", 25)
.withProperty("spring.data.gemfire.pool.ping-interval", 5000L)
.withProperty("spring.data.gemfire.pool.pr-single-hop-enabled", false)
.withProperty("spring.data.gemfire.pool.default.read-timeout", 5000L)
.withProperty("spring.data.gemfire.pool.read-timeout", 15000)
.withProperty("spring.data.gemfire.pool.retry-attempts", 2)
.withProperty("spring.data.gemfire.pool.server-group", "testGroup")
.withProperty("spring.data.gemfire.pool.subscription-enabled", true)
.withProperty("spring.data.gemfire.pool.TestPool.subscription-redundancy", 2);
this.applicationContext = newApplicationContext(testPropertySource, TestPoolConfiguration.class);
assertThat(this.applicationContext).isNotNull();
assertThat(this.applicationContext.containsBean("gemfireCache")).isTrue();
assertThat(this.applicationContext.containsBean("TestPool")).isTrue();
Pool testPool = this.applicationContext.getBean("TestPool", Pool.class);
assertThat(testPool).isNotNull();
assertThat(testPool.getFreeConnectionTimeout()).isEqualTo(5000);
assertThat(testPool.getIdleTimeout()).isEqualTo(10000L);
assertThat(testPool.getLoadConditioningInterval()).isEqualTo(100000);
assertThat(testPool.getLocators()).contains(new InetSocketAddress("skullbox", 11235));
assertThat(testPool.getMaxConnections()).isEqualTo(500);
assertThat(testPool.getMinConnections()).isEqualTo(25);
assertThat(testPool.getMultiuserAuthentication()).isFalse();
assertThat(testPool.getName()).isEqualTo("TestPool");
assertThat(testPool.getPingInterval()).isEqualTo(5000L);
assertThat(testPool.getPRSingleHopEnabled()).isFalse();
assertThat(testPool.getReadTimeout()).isEqualTo(15000);
assertThat(testPool.getRetryAttempts()).isEqualTo(1);
assertThat(testPool.getServerGroup()).isEqualTo("testGroup");
assertThat(testPool.getSubscriptionAckInterval()).isEqualTo(PoolFactory.DEFAULT_SUBSCRIPTION_ACK_INTERVAL);
assertThat(testPool.getSubscriptionEnabled()).isEqualTo(true);
assertThat(testPool.getSubscriptionMessageTrackingTimeout()).isEqualTo(PoolFactory.DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT);
assertThat(testPool.getSubscriptionRedundancy()).isEqualTo(2);
assertThat(testPool.getThreadLocalConnections()).isFalse();
}
@Test
public void multiPoolConfiguration() {
MockPropertySource testPropertySource = new MockPropertySource()
.withProperty("spring.data.gemfire.pool.free-connection-timeout", 5000)
.withProperty("spring.data.gemfire.pool.idle-timeout", 10000L)
.withProperty("spring.data.gemfire.pool.load-conditioning-interval", 120000)
.withProperty("spring.data.gemfire.pool.locators", "localhost[10334]")
.withProperty("spring.data.gemfire.pool.max-connections", 500)
.withProperty("spring.data.gemfire.pool.min-connections", 50)
.withProperty("spring.data.gemfire.pool.multi-user-authentication", true)
.withProperty("spring.data.gemfire.pool.ping-interval", 5000L)
.withProperty("spring.data.gemfire.pool.pr-single-hop-enabled", false)
.withProperty("spring.data.gemfire.pool.read-timeout", 15000L)
.withProperty("spring.data.gemfire.pool.retry-attempts", 2)
.withProperty("spring.data.gemfire.pool.server-group", "testGroup")
.withProperty("spring.data.gemfire.pool.socket-buffer-size", 8192)
.withProperty("spring.data.gemfire.pool.statistic-interval", 1000)
.withProperty("spring.data.gemfire.pool.subscription-ack-interval", 5000)
.withProperty("spring.data.gemfire.pool.subscription-enabled", true)
.withProperty("spring.data.gemfire.pool.subscription-message-tracking-timeout", 180000)
.withProperty("spring.data.gemfire.pool.subscription-redundancy", 2)
.withProperty("spring.data.gemfire.pool.thread-local-connections", true)
.withProperty("spring.data.gemfire.pool.default.free-connection-timeout", 15000)
.withProperty("spring.data.gemfire.pool.default.idle-timeout", 20000L)
.withProperty("spring.data.gemfire.pool.default.load-conditioning-interval", 180000)
.withProperty("spring.data.gemfire.pool.default.locators", "skullbox[11235]")
.withProperty("spring.data.gemfire.pool.default.max-connections", 275)
.withProperty("spring.data.gemfire.pool.default.min-connections", 27)
.withProperty("spring.data.gemfire.pool.default.multi-user-authentication", true)
.withProperty("spring.data.gemfire.pool.default.ping-interval", 15000L)
.withProperty("spring.data.gemfire.pool.default.pr-single-hop-enabled", false)
.withProperty("spring.data.gemfire.pool.default.read-timeout", 2000L)
.withProperty("spring.data.gemfire.pool.default.retry-attempts", 1)
.withProperty("spring.data.gemfire.pool.default.server-group", "testDefaultGroup")
.withProperty("spring.data.gemfire.pool.default.socket-buffer-size", 16384)
.withProperty("spring.data.gemfire.pool.default.statistic-interval", 500)
.withProperty("spring.data.gemfire.pool.default.subscription-ack-interval", 250)
.withProperty("spring.data.gemfire.pool.default.subscription-enabled", true)
.withProperty("spring.data.gemfire.pool.default.subscription-message-tracking-timeout", 300000)
.withProperty("spring.data.gemfire.pool.default.subscription-redundancy", 3)
.withProperty("spring.data.gemfire.pool.default.thread-local-connections", true)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.free-connection-timeout", 20000)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.idle-timeout", 15000L)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.load-conditioning-interval", 60000)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.servers", "jambox[12480]")
.withProperty("spring.data.gemfire.pool.TestPoolTwo.max-connections", 1000)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.min-connections", 100)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.multi-user-authentication", true)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.ping-interval", 20000L)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.pr-single-hop-enabled", false)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.read-timeout", 5000L)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.retry-attempts", 4)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.server-group", "testTwoGroup")
.withProperty("spring.data.gemfire.pool.TestPoolTwo.socket-buffer-size", 65536)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.statistic-interval", 2000)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.subscription-ack-interval", 500)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.subscription-enabled", true)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.subscription-message-tracking-timeout", 300000)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.subscription-redundancy", 4)
.withProperty("spring.data.gemfire.pool.TestPoolTwo.thread-local-connections", true);
this.applicationContext = newApplicationContext(testPropertySource, TestPoolsConfiguration.class);
assertThat(this.applicationContext).isNotNull();
assertThat(this.applicationContext.containsBean("gemfireCache")).isTrue();
assertThat(this.applicationContext.containsBean("TestPoolOne")).isTrue();
assertThat(this.applicationContext.containsBean("TestPoolTwo")).isTrue();
ClientCache gemfireCache = this.applicationContext.getBean(ClientCache.class);
assertThat(gemfireCache).isNotNull();
Pool defaultPool = gemfireCache.getDefaultPool();
assertPool(defaultPool, 15000, 20000L, 180000,
275, 27, true, "DEFAULT", 15000L,
false, 2000, 1, "testDefaultGroup",
16384, 500, 250, true,
300000, 3, true);
Pool testPoolOne = this.applicationContext.getBean("TestPoolOne", Pool.class);
assertPool(testPoolOne, 5000, 10000L, 120000,
500, 50, true, "TestPoolOne", 5000L,
false, 15000, 2, "testGroup",
8192, 1000, 5000, true,
180000, 2, true);
Pool testPoolTwo = this.applicationContext.getBean("TestPoolTwo", Pool.class);
assertPool(testPoolTwo, 20000, 15000L, 60000,
1000, 100, true, "TestPoolTwo", 20000L,
false, 5000, 4, "testTwoGroup",
65536, 2000, 500, true,
300000, 4, true);
}
@EnableGemFireMocking
@ClientCacheApplication
@EnablePool(name = "TestPool", idleTimeout = 10000L, maxConnections = 200, minConnections = 20)
static class TestPoolConfiguration {
@Bean
PoolConfigurer testPoolConfigurer() {
return (beanName, beanFactory) -> {
beanFactory.setLoadConditioningInterval(100000);
beanFactory.setRetryAttempts(1);
};
}
}
@EnableGemFireMocking
@ClientCacheApplication
@EnablePools(pools = { @EnablePool(name = "TestPoolOne"), @EnablePool(name = "TestPoolTwo") })
static class TestPoolsConfiguration {
}
}

View File

@@ -18,18 +18,30 @@ package org.springframework.data.gemfire.test.mock.config;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.client.ClientCacheFactory;
import org.apache.geode.cache.client.PoolFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
import org.springframework.data.gemfire.client.PoolFactoryBean;
import org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport;
import org.springframework.lang.Nullable;
/**
* The MockGemFireObjectsBeanPostProcessor class...
* The {@link MockGemFireObjectsBeanPostProcessor} class is a Spring {@link BeanPostProcessor} that applies
* mocks and spies to Spring Data GemFire / Spring Data Geode and Pivotal GemFire / Apache Geode objects
* and components.
*
* @author John Blum
* @since 1.0.0
* @see org.apache.geode.cache.CacheFactory
* @see org.apache.geode.cache.client.ClientCacheFactory
* @see org.apache.geode.cache.client.PoolFactory
* @see org.springframework.beans.factory.config.BeanPostProcessor
* @see org.springframework.data.gemfire.CacheFactoryBean
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
* @see org.springframework.data.gemfire.client.PoolFactoryBean
* @see org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport
* @since 2.0.0
*/
public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor {
@@ -37,7 +49,10 @@ public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor {
@Nullable @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return (bean instanceof CacheFactoryBean ? spyOnCacheFactoryBean((CacheFactoryBean) bean) : bean);
return (bean instanceof CacheFactoryBean ? spyOnCacheFactoryBean((CacheFactoryBean) bean)
: (bean instanceof PoolFactoryBean ? mockThePoolFactoryBean((PoolFactoryBean) bean)
: bean));
}
private Object spyOnCacheFactoryBean(CacheFactoryBean bean) {
@@ -47,6 +62,10 @@ public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor {
: SpyingCacheFactoryInitializer.spyOn(bean));
}
private Object mockThePoolFactoryBean(PoolFactoryBean bean) {
return MockingPoolFactoryInitializer.mock(bean);
}
protected static class SpyingCacheFactoryInitializer
implements CacheFactoryBean.CacheFactoryInitializer<CacheFactory> {
@@ -74,4 +93,17 @@ public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor {
return MockGemFireObjectsSupport.spyOn(clientCacheFactory);
}
}
protected static class MockingPoolFactoryInitializer implements PoolFactoryBean.PoolFactoryInitializer {
public static PoolFactoryBean mock(PoolFactoryBean poolFactoryBean) {
poolFactoryBean.setPoolFactoryInitializer(new MockingPoolFactoryInitializer());
return poolFactoryBean;
}
@Override
public PoolFactory initialize(PoolFactory poolFactory) {
return MockGemFireObjectsSupport.mockPoolFactory();
}
}
}