SGF-439 - Add 'durable-client-id' and 'durable-client-timeout' attributes to the <gfe:client-cache> namespace element for convenience.
(cherry picked from commit e74768f006d59210ddd3d4fe5294a60ca505674f) Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
@@ -24,6 +24,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.data.gemfire.CacheFactoryBean;
|
||||
import org.springframework.data.gemfire.GemfireUtils;
|
||||
import org.springframework.data.gemfire.config.GemfireConstants;
|
||||
import org.springframework.data.gemfire.util.DistributedSystemUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -56,11 +57,13 @@ import com.gemstone.gemfire.pdx.PdxSerializer;
|
||||
public class ClientCacheFactoryBean extends CacheFactoryBean implements ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
protected Boolean keepAlive = false;
|
||||
|
||||
protected Boolean readyForEvents = false;
|
||||
|
||||
protected Integer durableClientTimeout;
|
||||
|
||||
private Pool pool;
|
||||
|
||||
protected String durableClientId;
|
||||
protected String poolName;
|
||||
|
||||
@Override
|
||||
@@ -101,6 +104,8 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
|
||||
gemfireProperties = distributedSystemProperties;
|
||||
}
|
||||
|
||||
DistributedSystemUtils.configureDurableClient(gemfireProperties, durableClientId, durableClientTimeout);
|
||||
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
@@ -179,7 +184,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCacheFactory
|
||||
*/
|
||||
private ClientCacheFactory initializePool(ClientCacheFactory clientCacheFactory) {
|
||||
resolvePool(this.pool);
|
||||
resolvePool(pool);
|
||||
return clientCacheFactory;
|
||||
}
|
||||
|
||||
@@ -246,21 +251,62 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
|
||||
((ClientCache) cache).close(isKeepAlive());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends GemFireCache> getObjectType() {
|
||||
return (cache != null ? cache.getClass() : ClientCache.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setEnableAutoReconnect(final Boolean enableAutoReconnect) {
|
||||
throw new UnsupportedOperationException("Auto-reconnect is not supported on ClientCache.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the GemFire System property 'durable-client-id' to indicate to the server that this client is durable.
|
||||
*
|
||||
* @param durableClientId a String value indicating the durable client id.
|
||||
*/
|
||||
public void setDurableClientId(final String durableClientId) {
|
||||
this.durableClientId = durableClientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the GemFire System property 'durable-client-id' indicating to the server whether
|
||||
* this client is durable.
|
||||
*
|
||||
* @return a String value indicating the durable client id.
|
||||
*/
|
||||
public String getDurableClientId() {
|
||||
return durableClientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the GemFire System property 'durable-client-timeout' indicating to the server how long to track events
|
||||
* for the durable client when disconnected.
|
||||
*
|
||||
* @param durableClientTimeout an Integer value indicating the timeout in seconds for the server to keep
|
||||
* the durable client's queue around.
|
||||
*/
|
||||
public void setDurableClientTimeout(final Integer durableClientTimeout) {
|
||||
this.durableClientTimeout = durableClientTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the GemFire System property 'durable-client-timeout' indicating to the server how long
|
||||
* to track events for the durable client when disconnected.
|
||||
*
|
||||
* @return an Integer value indicating the timeout in seconds for the server to keep
|
||||
* the durable client's queue around.
|
||||
*/
|
||||
public Integer getDurableClientTimeout() {
|
||||
return durableClientTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Boolean getEnableAutoReconnect() {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends GemFireCache> getObjectType() {
|
||||
return (cache != null ? cache.getClass() : ClientCache.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the server(s) should keep the durable client's queue alive for the duration of the timeout
|
||||
* when the client voluntarily disconnects.
|
||||
@@ -271,6 +317,16 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
|
||||
this.keepAlive = keepAlive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user specified value for whether the server(s) should keep the durable client's queue alive
|
||||
* for the duration of the timeout when the client voluntarily disconnects.
|
||||
*
|
||||
* @return a boolean value indicating whether the server should keep the durable client's queues alive.
|
||||
*/
|
||||
public Boolean getKeepAlive() {
|
||||
return keepAlive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the server(s) should keep the durable client's queue alive for the duration of the timeout
|
||||
* when the client voluntarily disconnects.
|
||||
@@ -278,7 +334,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
|
||||
* @return a boolean value indicating whether the server should keep the durable client's queues alive.
|
||||
*/
|
||||
public boolean isKeepAlive() {
|
||||
return Boolean.TRUE.equals(this.keepAlive);
|
||||
return Boolean.TRUE.equals(getKeepAlive());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -311,10 +367,11 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the readyForEvents flag.
|
||||
* Sets the readyForEvents property to indicate whether the cache client should notify the server
|
||||
* that it is ready to receive updates.
|
||||
*
|
||||
* @param readyForEvents sets a boolean flag to notify the server that this durable client is ready
|
||||
* to receive updates.
|
||||
* @param readyForEvents sets a boolean flag to notify the server that this durable client
|
||||
* is ready to receive updates.
|
||||
* @see #getReadyForEvents()
|
||||
*/
|
||||
public void setReadyForEvents(Boolean readyForEvents){
|
||||
@@ -322,7 +379,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for the readyForEvents property.
|
||||
* Gets the user-specified value for the readyForEvents property.
|
||||
*
|
||||
* @return a boolean value indicating the state of the 'readyForEvents' property.
|
||||
*/
|
||||
|
||||
@@ -108,18 +108,6 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
|
||||
private String serverGroup = PoolFactory.DEFAULT_SERVER_GROUP;
|
||||
|
||||
public Pool getObject() throws Exception {
|
||||
return pool;
|
||||
}
|
||||
|
||||
public Class<?> getObjectType() {
|
||||
return (pool != null ? pool.getClass() : Pool.class);
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (!StringUtils.hasText(name)) {
|
||||
Assert.hasText(beanName, "Pool 'name' is required");
|
||||
@@ -184,14 +172,20 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
/**
|
||||
* Creates an instance of the GemFire PoolFactory interface to construct, configure and initialize a GemFire Pool.
|
||||
*
|
||||
* @return a PoolFactory implementation to create Pool.
|
||||
* @see com.gemstone.gemfire.cache.client.PoolFactory
|
||||
* @see com.gemstone.gemfire.cache.client.PoolManager#createFactory()
|
||||
*/
|
||||
protected PoolFactory createPoolFactory() {
|
||||
return PoolManager.createFactory();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
void resolveDistributedSystem() {
|
||||
if (DistributedSystemUtils.getDistributedSystem() == null) {
|
||||
if (DistributedSystemUtils.isNotConnected(DistributedSystemUtils.getDistributedSystem())) {
|
||||
doDistributedSystemConnect(resolveGemfireProperties());
|
||||
}
|
||||
}
|
||||
@@ -200,7 +194,7 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
Properties resolveGemfireProperties() {
|
||||
try {
|
||||
ClientCacheFactoryBean clientCacheFactoryBean = beanFactory.getBean(ClientCacheFactoryBean.class);
|
||||
return clientCacheFactoryBean.getProperties();
|
||||
return clientCacheFactoryBean.resolveProperties();
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
return null;
|
||||
@@ -208,8 +202,8 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
}
|
||||
|
||||
/**
|
||||
* A workaround to create a Pool if no ClientCache has been created yet. Initialize a client-like
|
||||
* Distributed System before initializing the Pool.
|
||||
* A workaround to create a Pool if no ClientCache has been created yet. Initialize a cache client-like
|
||||
* DistributedSystem before initializing the Pool.
|
||||
*
|
||||
* @param properties GemFire System Properties.
|
||||
* @see java.util.Properties
|
||||
@@ -235,6 +229,18 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
}
|
||||
}
|
||||
|
||||
public Pool getObject() throws Exception {
|
||||
return pool;
|
||||
}
|
||||
|
||||
public Class<?> getObjectType() {
|
||||
return (pool != null ? pool.getClass() : Pool.class);
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
@@ -38,8 +38,10 @@ class ClientCacheParser extends CacheParser {
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
super.doParse(element, parserContext, builder);
|
||||
ParsingUtils.setPropertyValue(element, builder, "keep-alive", "keepAlive");
|
||||
ParsingUtils.setPropertyValue(element, builder, "pool-name", "poolName");
|
||||
ParsingUtils.setPropertyValue(element, builder, "durable-client-id");
|
||||
ParsingUtils.setPropertyValue(element, builder, "durable-client-timeout");
|
||||
ParsingUtils.setPropertyValue(element, builder, "keep-alive");
|
||||
ParsingUtils.setPropertyValue(element, builder, "pool-name");
|
||||
ParsingUtils.setPropertyValue(element, builder, "ready-for-events");
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,16 @@
|
||||
|
||||
package org.springframework.data.gemfire.util;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.gemstone.gemfire.cache.server.CacheServer;
|
||||
import com.gemstone.gemfire.distributed.DistributedSystem;
|
||||
import com.gemstone.gemfire.distributed.internal.DistributionConfig;
|
||||
import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
|
||||
import com.gemstone.gemfire.internal.DistributionLocator;
|
||||
import com.gemstone.gemfire.management.internal.cli.util.spring.StringUtils;
|
||||
|
||||
/**
|
||||
* DistributedSystemUtils is an abstract utility class for working with the GemFire DistributedSystem.
|
||||
@@ -28,11 +34,29 @@ import com.gemstone.gemfire.internal.DistributionLocator;
|
||||
* @see com.gemstone.gemfire.distributed.DistributedSystem
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class DistributedSystemUtils {
|
||||
|
||||
public static final int DEFAULT_CACHE_SERVER_PORT = CacheServer.DEFAULT_PORT;
|
||||
public static final int DEFAULT_LOCATOR_PORT = DistributionLocator.DEFAULT_LOCATOR_PORT;
|
||||
|
||||
public static final String DURABLE_CLIENT_ID_PROPERTY_NAME = DistributionConfig.DURABLE_CLIENT_ID_NAME;
|
||||
public static final String DURABLE_CLIENT_TIMEOUT_PROPERTY_NAME = DistributionConfig.DURABLE_CLIENT_TIMEOUT_NAME;
|
||||
|
||||
public static Properties configureDurableClient(Properties gemfireProperties, String durableClientId, Integer durableClientTimeout) {
|
||||
if (StringUtils.hasText(durableClientId)) {
|
||||
Assert.notNull(gemfireProperties, "gemfireProperties must not be null");
|
||||
|
||||
gemfireProperties.setProperty(DURABLE_CLIENT_ID_PROPERTY_NAME, durableClientId);
|
||||
|
||||
if (durableClientTimeout != null) {
|
||||
gemfireProperties.setProperty(DURABLE_CLIENT_TIMEOUT_PROPERTY_NAME, durableClientTimeout.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends DistributedSystem> T getDistributedSystem() {
|
||||
return (T) InternalDistributedSystem.getAnyInstance();
|
||||
@@ -42,4 +66,8 @@ public abstract class DistributedSystemUtils {
|
||||
return (distributedSystem != null && distributedSystem.isConnected());
|
||||
}
|
||||
|
||||
public static boolean isNotConnected(DistributedSystem distributedSystem) {
|
||||
return !isConnected(distributedSystem);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -349,6 +349,27 @@ Defines a GemFire Client Cache instance used for creating or retrieving 'regions
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="cacheBaseType">
|
||||
<xsd:attribute name="durable-client-id" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Used only for clients in a client/server installation. If set, this indicates that the client is durable
|
||||
and identifies the client. The ID is used by servers to reestablish any messaging that was interrupted
|
||||
by client downtime. The default value is unset. In addition, this attribute value overrides any setting
|
||||
specified in gemfire.properties passed using 'properties-ref'.
|
||||
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="durable-client-timeout" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Used only for clients in a client/server installation. Number of seconds this client can remain disconnected
|
||||
from its server and have the server continue to accumulate durable events for it. The default value is 300 seconds.
|
||||
In addition, this attribute value overrides any setting specified in gemfire.properties passed using 'properties-ref'.
|
||||
Also, durable-client-timeout is only used if durable-client-id is set.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="keep-alive" type="xsd:string" use="optional" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
|
||||
@@ -16,11 +16,13 @@
|
||||
|
||||
package org.springframework.data.gemfire.client;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -42,6 +44,7 @@ import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.data.gemfire.TestUtils;
|
||||
import org.springframework.data.gemfire.config.GemfireConstants;
|
||||
import org.springframework.data.gemfire.util.DistributedSystemUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.CacheClosedException;
|
||||
import com.gemstone.gemfire.cache.GemFireCache;
|
||||
@@ -60,13 +63,21 @@ import com.gemstone.gemfire.pdx.PdxSerializer;
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCacheFactory
|
||||
* @see com.gemstone.gemfire.cache.client.Pool
|
||||
* @see com.gemstone.gemfire.distributed.DistributedSystem
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public class ClientCacheFactoryBeanTest {
|
||||
|
||||
protected Properties createProperties(String key, String value) {
|
||||
Properties properties = new Properties();
|
||||
return addProperty(null, key, value);
|
||||
}
|
||||
|
||||
protected Properties addProperty(Properties properties, String key, String value) {
|
||||
properties = (properties != null ? properties : new Properties());
|
||||
properties.setProperty(key, value);
|
||||
return properties;
|
||||
}
|
||||
@@ -101,12 +112,52 @@ public class ClientCacheFactoryBeanTest {
|
||||
|
||||
Properties resolvedProperties = clientCacheFactoryBean.resolveProperties();
|
||||
|
||||
assertNotNull(resolvedProperties);
|
||||
assertNotSame(gemfireProperties, resolvedProperties);
|
||||
assertNotSame(distributedSystemProperties, resolvedProperties);
|
||||
assertEquals(2, resolvedProperties.size());
|
||||
assertEquals("test", resolvedProperties.getProperty("gf"));
|
||||
assertEquals("mock", resolvedProperties.getProperty("ds"));
|
||||
assertThat(resolvedProperties, is(notNullValue()));
|
||||
assertThat(resolvedProperties, is(not(sameInstance(gemfireProperties))));
|
||||
assertThat(resolvedProperties, is(not(sameInstance(distributedSystemProperties))));
|
||||
assertThat(resolvedProperties.size(), is(equalTo(2)));
|
||||
assertThat(resolvedProperties.containsKey(DistributedSystemUtils.DURABLE_CLIENT_ID_PROPERTY_NAME), is(false));
|
||||
assertThat(resolvedProperties.containsKey(DistributedSystemUtils.DURABLE_CLIENT_TIMEOUT_PROPERTY_NAME), is(false));
|
||||
assertThat(resolvedProperties.getProperty("gf"), is(equalTo("test")));
|
||||
assertThat(resolvedProperties.getProperty("ds"), is(equalTo("mock")));
|
||||
|
||||
verify(mockDistributedSystem, times(1)).isConnected();
|
||||
verify(mockDistributedSystem, times(1)).getProperties();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolvePropertiesWhenDistributedSystemIsConnectedAndClientIsDurable() {
|
||||
Properties gemfireProperties = DistributedSystemUtils.configureDurableClient(createProperties("gf", "test"),
|
||||
"123", 600);
|
||||
|
||||
Properties distributedSystemProperties = DistributedSystemUtils.configureDurableClient(
|
||||
createProperties("ds", "mock"), "987", 300);
|
||||
|
||||
final DistributedSystem mockDistributedSystem = mock(DistributedSystem.class, "MockDistributedSystem");
|
||||
|
||||
when(mockDistributedSystem.isConnected()).thenReturn(true);
|
||||
when(mockDistributedSystem.getProperties()).thenReturn(distributedSystemProperties);
|
||||
|
||||
ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean() {
|
||||
@SuppressWarnings("unchecked") @Override <T extends DistributedSystem> T getDistributedSystem() {
|
||||
return (T) mockDistributedSystem;
|
||||
}
|
||||
};
|
||||
|
||||
clientCacheFactoryBean.setProperties(gemfireProperties);
|
||||
|
||||
Properties resolvedProperties = clientCacheFactoryBean.resolveProperties();
|
||||
|
||||
assertThat(resolvedProperties, is(notNullValue()));
|
||||
assertThat(resolvedProperties, is(not(sameInstance(gemfireProperties))));
|
||||
assertThat(resolvedProperties, is(not(sameInstance(distributedSystemProperties))));
|
||||
assertThat(resolvedProperties.size(), is(equalTo(4)));
|
||||
assertThat(resolvedProperties.getProperty("gf"), is(equalTo("test")));
|
||||
assertThat(resolvedProperties.getProperty("ds"), is(equalTo("mock")));
|
||||
assertThat(resolvedProperties.getProperty(DistributedSystemUtils.DURABLE_CLIENT_ID_PROPERTY_NAME),
|
||||
is(equalTo("123")));
|
||||
assertThat(resolvedProperties.getProperty(DistributedSystemUtils.DURABLE_CLIENT_TIMEOUT_PROPERTY_NAME),
|
||||
is(equalTo("600")));
|
||||
|
||||
verify(mockDistributedSystem, times(1)).isConnected();
|
||||
verify(mockDistributedSystem, times(1)).getProperties();
|
||||
@@ -252,10 +303,13 @@ public class ClientCacheFactoryBeanTest {
|
||||
|
||||
@Test
|
||||
public void createCache() {
|
||||
BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockSpringBeanFactory");
|
||||
ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class, "MockGemFireClientCacheFactory");
|
||||
ClientCache mockClientCache = mock(ClientCache.class, "MockGemFireClientCache");
|
||||
Pool mockPool = mock(Pool.class, "MockGemFirePool");
|
||||
BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockBeanFactory");
|
||||
|
||||
ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class, "MockClientCacheFactory");
|
||||
|
||||
ClientCache mockClientCache = mock(ClientCache.class, "MockClientCache");
|
||||
|
||||
Pool mockPool = mock(Pool.class, "MockPool");
|
||||
|
||||
when(mockClientCacheFactory.create()).thenReturn(mockClientCache);
|
||||
when(mockBeanFactory.isTypeMatch(eq("testCreateCache.Pool"), eq(Pool.class))).thenReturn(true);
|
||||
|
||||
@@ -46,7 +46,8 @@ import com.gemstone.gemfire.cache.LoaderHelper;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* The ClientCacheSecurityTest class...
|
||||
* The ClientCacheSecurityTest class is a test suite with test cases testing SSL configuration between a GemFire client
|
||||
* and server using the cluster-ssl-* GemFire System properties.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.springframework.data.gemfire.GemfireUtils;
|
||||
import org.springframework.data.gemfire.process.ProcessWrapper;
|
||||
import org.springframework.data.gemfire.test.AbstractGemFireClientServerIntegrationTest;
|
||||
import org.springframework.data.gemfire.test.support.ThreadUtils;
|
||||
import org.springframework.data.gemfire.util.DistributedSystemUtils;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -95,6 +96,8 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ
|
||||
private static final String CLIENT_CACHE_INTERESTS_RESULT_POLICY_SYSTEM_PROPERTY =
|
||||
"gemfire.cache.client.interests.result-policy";
|
||||
|
||||
private static final String DURABLE_CLIENT_TIMEOUT_SYSTEM_PROPERTY = "gemfire.cache.client.durable-client-timeout";
|
||||
|
||||
private static final String SERVER_HOST = "localhost";
|
||||
|
||||
@Autowired
|
||||
@@ -119,6 +122,14 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
assertThat(clientCache.getDistributedSystem().getProperties().getProperty(
|
||||
DistributedSystemUtils.DURABLE_CLIENT_ID_PROPERTY_NAME),
|
||||
is(equalTo(DurableClientCacheIntegrationTest.class.getSimpleName())));
|
||||
|
||||
assertThat(clientCache.getDistributedSystem().getProperties().getProperty(
|
||||
DistributedSystemUtils.DURABLE_CLIENT_TIMEOUT_PROPERTY_NAME),
|
||||
is(equalTo(RUN_COUNT.get() == 1 ? "300" : "600")));
|
||||
|
||||
assertRegion(example, "Example", DataPolicy.NORMAL);
|
||||
}
|
||||
|
||||
@@ -127,8 +138,7 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ
|
||||
if (RUN_COUNT.get() == 1) {
|
||||
closeApplicationContext();
|
||||
runClientCacheProducer();
|
||||
System.setProperty(CLIENT_CACHE_INTERESTS_RESULT_POLICY_SYSTEM_PROPERTY,
|
||||
InterestResultPolicyType.NONE.name());
|
||||
setSystemProperties();
|
||||
RUN_COUNT.incrementAndGet();
|
||||
}
|
||||
|
||||
@@ -162,6 +172,11 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ
|
||||
}
|
||||
}
|
||||
|
||||
protected void setSystemProperties() {
|
||||
System.setProperty(CLIENT_CACHE_INTERESTS_RESULT_POLICY_SYSTEM_PROPERTY, InterestResultPolicyType.NONE.name());
|
||||
System.setProperty(DURABLE_CLIENT_TIMEOUT_SYSTEM_PROPERTY, "600");
|
||||
}
|
||||
|
||||
protected void waitForRegionEntryEvents() {
|
||||
ThreadUtils.timedWait(TimeUnit.SECONDS.toMillis(5), TimeUnit.MILLISECONDS.toMillis(500),
|
||||
new ThreadUtils.WaitCondition() {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.data.gemfire.client;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
@@ -30,11 +32,12 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.data.gemfire.TestUtils;
|
||||
@@ -57,26 +60,24 @@ import com.gemstone.gemfire.cache.client.PoolFactory;
|
||||
*/
|
||||
public class PoolFactoryBeanTest {
|
||||
|
||||
@Test
|
||||
public void testGetObjectType() {
|
||||
assertEquals(Pool.class, new PoolFactoryBean().getObjectType());
|
||||
}
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void testIsSingleton() {
|
||||
assertTrue(new PoolFactoryBean().isSingleton());
|
||||
}
|
||||
@SuppressWarnings("deprecation")
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockBeanFactory");
|
||||
|
||||
@Test
|
||||
public void testAfterPropertiesSet() throws Exception {
|
||||
BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockSpringBeanFactory");
|
||||
final PoolFactory mockPoolFactory = mock(PoolFactory.class, "MockGemFirePoolFactory");
|
||||
Pool mockPool = mock(Pool.class, "GemFirePool");
|
||||
final PoolFactory mockPoolFactory = mock(PoolFactory.class, "MockPoolFactory");
|
||||
|
||||
Pool mockPool = mock(Pool.class, "MockPool");
|
||||
|
||||
final Properties gemfireProperties = new Properties();
|
||||
|
||||
gemfireProperties.setProperty("name", "testAfterPropertiesSet");
|
||||
|
||||
ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean();
|
||||
|
||||
clientCacheFactoryBean.setProperties(gemfireProperties);
|
||||
|
||||
when(mockBeanFactory.getBean(eq(ClientCacheFactoryBean.class))).thenReturn(clientCacheFactoryBean);
|
||||
@@ -139,39 +140,40 @@ public class PoolFactoryBeanTest {
|
||||
verify(mockPoolFactory, times(1)).create(eq("GemFirePool"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithNoLocatorsServersSpecified() throws Exception {
|
||||
try {
|
||||
PoolFactoryBean poolFactoryBean = new PoolFactoryBean();
|
||||
@Test
|
||||
public void afterPropertiesSetWithUnspecifiedName() throws Exception {
|
||||
PoolFactoryBean poolFactoryBean = new PoolFactoryBean();
|
||||
|
||||
poolFactoryBean.setName("GemFirePool");
|
||||
poolFactoryBean.setLocators((Collection) null);
|
||||
poolFactoryBean.setServers(Collections.<InetSocketAddress>emptyList());
|
||||
poolFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("at least one GemFire Locator or Server is required", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
poolFactoryBean.setBeanName(null);
|
||||
poolFactoryBean.setName(null);
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAfterPropertiesSetWithUnspecifiedName() throws Exception {
|
||||
try {
|
||||
PoolFactoryBean poolFactoryBean = new PoolFactoryBean();
|
||||
poolFactoryBean.setBeanName(null);
|
||||
poolFactoryBean.setName(null);
|
||||
poolFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
assertEquals("Pool 'name' is required", expected.getMessage());
|
||||
throw expected;
|
||||
}
|
||||
expectedException.expect(IllegalArgumentException.class);
|
||||
expectedException.expectCause(is(nullValue(Throwable.class)));
|
||||
expectedException.expectMessage("Pool 'name' is required");
|
||||
|
||||
poolFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveGemfireProperties() {
|
||||
BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockSpringBeanFactory");
|
||||
@SuppressWarnings("deprecation")
|
||||
public void afterPropertiesSetWithNoLocatorsOrServersSpecified() throws Exception {
|
||||
PoolFactoryBean poolFactoryBean = new PoolFactoryBean();
|
||||
|
||||
poolFactoryBean.setBeanName("GemFirePool");
|
||||
poolFactoryBean.setLocators(null);
|
||||
poolFactoryBean.setServers(Collections.<InetSocketAddress>emptyList());
|
||||
|
||||
expectedException.expect(IllegalArgumentException.class);
|
||||
expectedException.expectCause(is(nullValue(Throwable.class)));
|
||||
expectedException.expectMessage("at least one GemFire Locator or Server is required");
|
||||
|
||||
poolFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveGemfireProperties() {
|
||||
BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockBeanFactory");
|
||||
|
||||
ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean();
|
||||
|
||||
when(mockBeanFactory.getBean(eq(ClientCacheFactoryBean.class))).thenReturn(clientCacheFactoryBean);
|
||||
@@ -191,8 +193,8 @@ public class PoolFactoryBeanTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveUnresolvableGemfireProperties() {
|
||||
BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockSpringBeanFactory");
|
||||
public void resolveUnresolvableGemfireProperties() {
|
||||
BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockBeanFactory");
|
||||
|
||||
when(mockBeanFactory.getBean(eq(ClientCacheFactoryBean.class))).thenThrow(
|
||||
new NoSuchBeanDefinitionException("TEST"));
|
||||
@@ -205,8 +207,8 @@ public class PoolFactoryBeanTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroy() throws Exception {
|
||||
Pool mockPool = mock(Pool.class, "MockGemFirePool");
|
||||
public void destroy() throws Exception {
|
||||
Pool mockPool = mock(Pool.class, "MockPool");
|
||||
|
||||
when(mockPool.isDestroyed()).thenReturn(false);
|
||||
|
||||
@@ -222,7 +224,7 @@ public class PoolFactoryBeanTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroyNonSpringBasedPool() throws Exception {
|
||||
public void destroyWithNonSpringBasedPool() throws Exception {
|
||||
Pool mockPool = mock(Pool.class, "MockGemFirePool");
|
||||
|
||||
PoolFactoryBean poolFactoryBean = new PoolFactoryBean();
|
||||
@@ -237,11 +239,21 @@ public class PoolFactoryBeanTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroyWithUninitializedPool() throws Exception {
|
||||
public void destroyWithUninitializedPool() throws Exception {
|
||||
PoolFactoryBean poolFactoryBean = new PoolFactoryBean();
|
||||
|
||||
poolFactoryBean.setPool(null);
|
||||
poolFactoryBean.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getObjectType() {
|
||||
assertEquals(Pool.class, new PoolFactoryBean().getObjectType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSingleton() {
|
||||
assertTrue(new PoolFactoryBean().isSingleton());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ public class ClientCacheNamespaceTest {
|
||||
assertThat(clientCacheFactoryBean.isLazyInitialize(), is(true));
|
||||
assertThat(clientCacheFactoryBean.getCopyOnRead(), is(true));
|
||||
assertThat(clientCacheFactoryBean.getCriticalHeapPercentage(), is(equalTo(0.85f)));
|
||||
assertThat(clientCacheFactoryBean.getDurableClientId(), is(equalTo("TestDurableClientId")));
|
||||
assertThat(clientCacheFactoryBean.getDurableClientTimeout(), is(equalTo(600)));
|
||||
assertThat(clientCacheFactoryBean.getEvictionHeapPercentage(), is(equalTo(0.65f)));
|
||||
assertThat((PdxSerializer) clientCacheFactoryBean.getPdxSerializer(), is(equalTo(reflectionPdxSerializer)));
|
||||
assertThat(clientCacheFactoryBean.getPdxIgnoreUnreadFields(), is(true));
|
||||
|
||||
@@ -40,6 +40,8 @@ public class MockClientCacheFactoryBean extends ClientCacheFactoryBean {
|
||||
this.cacheXml = clientCacheFactoryBean.getCacheXml();
|
||||
this.copyOnRead = clientCacheFactoryBean.getCopyOnRead();
|
||||
this.criticalHeapPercentage = clientCacheFactoryBean.getCriticalHeapPercentage();
|
||||
this.durableClientId = clientCacheFactoryBean.getDurableClientId();
|
||||
this.durableClientTimeout = clientCacheFactoryBean.getDurableClientTimeout();
|
||||
this.dynamicRegionSupport = clientCacheFactoryBean.getDynamicRegionSupport();
|
||||
this.evictionHeapPercentage = clientCacheFactoryBean.getEvictionHeapPercentage();
|
||||
this.gatewayConflictResolver = clientCacheFactoryBean.getGatewayConflictResolver();
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
">
|
||||
|
||||
<util:properties id="client.properties">
|
||||
<util:properties id="clientProperties">
|
||||
<prop key="client.server.host">localhost</prop>
|
||||
<prop key="client.server.port">31517</prop>
|
||||
<prop key="gemfire.security.ssl.enabled">true</prop>
|
||||
@@ -23,7 +23,7 @@
|
||||
<prop key="gemfire.security.ssl.keystore.type">jks</prop>
|
||||
</util:properties>
|
||||
|
||||
<context:property-placeholder properties-ref="client.properties" system-properties-mode="FALLBACK"/>
|
||||
<context:property-placeholder properties-ref="clientProperties" system-properties-mode="FALLBACK"/>
|
||||
|
||||
<util:properties id="gemfireProperties">
|
||||
<prop key="cluster-ssl-enabled">${gemfire.security.ssl.enabled}</prop>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
">
|
||||
|
||||
<util:properties id="clientProperties">
|
||||
<prop key="gemfire.cache.client.durable-client-id">DurableClientCacheIntegrationTest</prop>
|
||||
<prop key="gemfire.cache.client.server.host">localhost</prop>
|
||||
<prop key="gemfire.cache.client.server.port">24842</prop>
|
||||
</util:properties>
|
||||
@@ -21,7 +22,7 @@
|
||||
<bean class="org.springframework.data.gemfire.client.DurableClientCacheIntegrationTest$ClientCacheBeanPostProcessor"/>
|
||||
|
||||
<util:properties id="gemfireProperties">
|
||||
<prop key="durable-client-id">DurableClientCacheIntegrationTestClientId</prop>
|
||||
<prop key="durable-client-id">TestDurableClientId</prop>
|
||||
<prop key="durable-client-timeout">300</prop>
|
||||
<prop key="log-level">warning</prop>
|
||||
<prop key="mcast-port">0</prop>
|
||||
@@ -32,8 +33,10 @@
|
||||
<gfe:server host="${gemfire.cache.client.server.host}" port="${gemfire.cache.client.server.port}"/>
|
||||
</gfe:pool>
|
||||
|
||||
<gfe:client-cache properties-ref="gemfireProperties" keep-alive="true" pool-name="gemfireServerPool" ready-for-events="true"
|
||||
use-bean-factory-locator="false"/>
|
||||
<gfe:client-cache properties-ref="gemfireProperties" pool-name="gemfireServerPool" use-bean-factory-locator="false"
|
||||
durable-client-id="${gemfire.cache.client.durable-client-id}"
|
||||
durable-client-timeout="${gemfire.cache.client.durable-client-timeout:}"
|
||||
keep-alive="true" ready-for-events="true"/>
|
||||
|
||||
<gfe:client-region id="Example" pool-name="gemfireServerPool" shortcut="CACHING_PROXY">
|
||||
<gfe:cache-listener>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
<bean id="reflectionPdxSerializer" class="com.gemstone.gemfire.pdx.ReflectionBasedAutoSerializer"/>
|
||||
|
||||
<gfe:client-cache cache-xml-location="/path/to/bogus/cache.xml" properties-ref="gemfireProperties" lazy-init="true"
|
||||
durable-client-id="TestDurableClientId" durable-client-timeout="600"
|
||||
copy-on-read="true" critical-heap-percentage="0.85" eviction-heap-percentage="0.65"
|
||||
pdx-serializer-ref="reflectionPdxSerializer" pdx-ignore-unread-fields="true" pdx-persistent="false"
|
||||
pdx-read-serialized="true" keep-alive="true" pool-name="serverPool" ready-for-events="false"/>
|
||||
|
||||
Reference in New Issue
Block a user