SGF-414 - Resolve incompatibility between the DistributedSystem created by the PoolFactoryBean and the DistributedSystem resolved by the ClientCacheFactoryBean when SSL is configured.
(cherry picked from commit 4f2eb221636971ed640ff4cb589f54e1207603d1) Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
@@ -38,7 +38,6 @@ import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import com.gemstone.gemfire.GemFireCheckedException;
|
||||
import com.gemstone.gemfire.GemFireException;
|
||||
@@ -203,40 +202,6 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class to avoid a hard dependency on the GemFire 6.6 API.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
private class PdxOptions implements Runnable {
|
||||
|
||||
private final CacheFactory factory;
|
||||
|
||||
private PdxOptions(CacheFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (pdxSerializer != null) {
|
||||
Assert.isAssignable(PdxSerializer.class, pdxSerializer.getClass(), "Invalid pdx serializer used");
|
||||
factory.setPdxSerializer((PdxSerializer) pdxSerializer);
|
||||
}
|
||||
if (pdxDiskStoreName != null) {
|
||||
factory.setPdxDiskStore(pdxDiskStoreName);
|
||||
}
|
||||
if (pdxIgnoreUnreadFields != null) {
|
||||
factory.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields);
|
||||
}
|
||||
if (pdxPersistent != null) {
|
||||
factory.setPdxPersistent(pdxPersistent);
|
||||
}
|
||||
if (pdxReadSerialized != null) {
|
||||
factory.setPdxReadSerialized(pdxReadSerialized);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
@@ -327,38 +292,39 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
catch (CacheClosedException ex) {
|
||||
cacheResolutionMessagePrefix = "Created new";
|
||||
initDynamicRegionFactory();
|
||||
return (Cache) createCache(prepareFactory(createFactory(getProperties())));
|
||||
return (Cache) createCache(prepareFactory(createFactory(resolveProperties())));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the GemFire Cache by looking up any existing GemFire Cache instance.
|
||||
* Fetches an existing GemFire Cache instance from the CacheFactory.
|
||||
*
|
||||
* @param <T> parameterized Class type extension of GemFireCache.
|
||||
* @return the existing GemFire Cache instance if available.
|
||||
* @throws com.gemstone.gemfire.cache.CacheClosedException if an existing GemFire Cache instance does not exist.
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @see com.gemstone.gemfire.cache.CacheFactory#getAnyInstance()
|
||||
*/
|
||||
protected GemFireCache fetchCache() {
|
||||
return (cache != null ? cache : CacheFactory.getAnyInstance());
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends GemFireCache> T fetchCache() {
|
||||
return (T) (cache != null ? cache : CacheFactory.getAnyInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new GemFire cache instance using the provided factory.
|
||||
* Resolves the GemFire System properties used to configure the GemFire Cache instance.
|
||||
*
|
||||
* @param factory the appropriate GemFire factory used to create a cache instance.
|
||||
* @return an instance of the GemFire cache.
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @see com.gemstone.gemfire.cache.CacheFactory#create()
|
||||
* @return a Properties object containing GemFire System properties used to configure the GemFire Cache instance.
|
||||
* @see #getProperties()
|
||||
*/
|
||||
protected GemFireCache createCache(Object factory) {
|
||||
return (cache != null ? cache : ((CacheFactory) factory).create());
|
||||
protected Properties resolveProperties() {
|
||||
return getProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of GemFire factory initialized with the given GemFire System Properties
|
||||
* to create an instance of the cache.
|
||||
* to create an instance of a GemFire cache.
|
||||
*
|
||||
* @param gemfireProperties a Properties object containing GemFire System Properties.
|
||||
* @param gemfireProperties a Properties object containing GemFire System properties.
|
||||
* @return an instance of a GemFire factory used to create a GemFire cache instance.
|
||||
* @see java.util.Properties
|
||||
* @see com.gemstone.gemfire.cache.CacheFactory
|
||||
@@ -371,19 +337,31 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
* Initializes the GemFire factory used to create the GemFire cache instance. Sets PDX options
|
||||
* specified by the user.
|
||||
*
|
||||
* @param factory the GemFire factory used to create an instance of the cache.
|
||||
* @return the initialized GemFire factory.
|
||||
* @see #setPdxOptions(Object)
|
||||
* @param factory the GemFire factory used to create an instance of the GemFire cache.
|
||||
* @return the initialized GemFire cache factory.
|
||||
* @see #isPdxOptionsSpecified()
|
||||
*/
|
||||
protected Object prepareFactory(Object factory) {
|
||||
if (isPdxOptionsSpecified()) {
|
||||
Assert.isTrue(ClassUtils.isPresent("com.gemstone.gemfire.pdx.PdxSerializer", beanClassLoader),
|
||||
"Unable set PDX options since GemFire 6.6 or later was not detected.");
|
||||
setPdxOptions(factory);
|
||||
}
|
||||
CacheFactory cacheFactory = (CacheFactory) factory;
|
||||
|
||||
//return (isCacheXmlAvailable() ? ((CacheFactory) factory).set(
|
||||
// DistributionConfig.CACHE_XML_FILE_NAME, getCacheXmlFile().getAbsolutePath()) : factory);
|
||||
if (pdxSerializer != null) {
|
||||
Assert.isAssignable(PdxSerializer.class, pdxSerializer.getClass(), "Invalid pdx serializer used");
|
||||
cacheFactory.setPdxSerializer((PdxSerializer) pdxSerializer);
|
||||
}
|
||||
if (pdxDiskStoreName != null) {
|
||||
cacheFactory.setPdxDiskStore(pdxDiskStoreName);
|
||||
}
|
||||
if (pdxIgnoreUnreadFields != null) {
|
||||
cacheFactory.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields);
|
||||
}
|
||||
if (pdxPersistent != null) {
|
||||
cacheFactory.setPdxPersistent(pdxPersistent);
|
||||
}
|
||||
if (pdxReadSerialized != null) {
|
||||
cacheFactory.setPdxReadSerialized(pdxReadSerialized);
|
||||
}
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
@@ -399,17 +377,17 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the PDX properties for the given Cache factory. Note, this is implementation specific
|
||||
* as it depends on the type of Cache factory used to create the Cache.
|
||||
* Creates a new GemFire cache instance using the provided factory.
|
||||
*
|
||||
* @param factory the GemFire CacheFactory used to apply the PDX configuration settings.
|
||||
* @see com.gemstone.gemfire.cache.CacheFactory
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCacheFactory
|
||||
* @param <T> parameterized Class type extension of GemFireCache.
|
||||
* @param factory the appropriate GemFire factory used to create a cache instance.
|
||||
* @return an instance of the GemFire cache.
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @see com.gemstone.gemfire.cache.CacheFactory#create()
|
||||
*/
|
||||
protected void setPdxOptions(Object factory) {
|
||||
if (factory instanceof CacheFactory) {
|
||||
new PdxOptions((CacheFactory) factory).run();
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends GemFireCache> T createCache(Object factory) {
|
||||
return (T) (cache != null ? cache : ((CacheFactory) factory).create());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,12 +399,12 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
* @throws IOException if the cache.xml Resource could not be loaded and applied to the Cache instance.
|
||||
* @see com.gemstone.gemfire.cache.Cache#loadCacheXml(java.io.InputStream)
|
||||
* @see #getCacheXml()
|
||||
* @see #setHeapPercentages(com.gemstone.gemfire.cache.Cache)
|
||||
* @see #registerTransactionListeners(com.gemstone.gemfire.cache.Cache)
|
||||
* @see #registerTransactionWriter(com.gemstone.gemfire.cache.Cache)
|
||||
* @see #setHeapPercentages(com.gemstone.gemfire.cache.GemFireCache)
|
||||
* @see #registerTransactionListeners(com.gemstone.gemfire.cache.GemFireCache)
|
||||
* @see #registerTransactionWriter(com.gemstone.gemfire.cache.GemFireCache)
|
||||
* @see #registerJndiDataSources()
|
||||
*/
|
||||
protected Cache postProcess(Cache cache) throws IOException {
|
||||
protected <T extends GemFireCache> T postProcess(T cache) throws IOException {
|
||||
Resource localCacheXml = getCacheXml();
|
||||
|
||||
// load cache.xml Resource and initialize the Cache
|
||||
@@ -442,19 +420,19 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
cache.setCopyOnRead(this.copyOnRead);
|
||||
}
|
||||
if (gatewayConflictResolver != null) {
|
||||
cache.setGatewayConflictResolver((GatewayConflictResolver) gatewayConflictResolver);
|
||||
((Cache) cache).setGatewayConflictResolver((GatewayConflictResolver) gatewayConflictResolver);
|
||||
}
|
||||
if (lockLease != null) {
|
||||
cache.setLockLease(lockLease);
|
||||
((Cache) cache).setLockLease(lockLease);
|
||||
}
|
||||
if (lockTimeout != null) {
|
||||
cache.setLockTimeout(lockTimeout);
|
||||
((Cache) cache).setLockTimeout(lockTimeout);
|
||||
}
|
||||
if (messageSyncInterval != null) {
|
||||
cache.setMessageSyncInterval(messageSyncInterval);
|
||||
((Cache) cache).setMessageSyncInterval(messageSyncInterval);
|
||||
}
|
||||
if (searchTimeout != null) {
|
||||
cache.setSearchTimeout(searchTimeout);
|
||||
((Cache) cache).setSearchTimeout(searchTimeout);
|
||||
}
|
||||
|
||||
setHeapPercentages(cache);
|
||||
@@ -466,7 +444,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private void setHeapPercentages(Cache cache) {
|
||||
private void setHeapPercentages(GemFireCache cache) {
|
||||
if (criticalHeapPercentage != null) {
|
||||
Assert.isTrue(criticalHeapPercentage > 0.0 && criticalHeapPercentage <= 100.0,
|
||||
String.format("'criticalHeapPercentage' (%1$s) is invalid; must be > 0.0 and <= 100.0",
|
||||
@@ -483,14 +461,14 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private void registerTransactionListeners(Cache cache) {
|
||||
private void registerTransactionListeners(GemFireCache cache) {
|
||||
for (TransactionListener transactionListener : CollectionUtils.nullSafeCollection(transactionListeners)) {
|
||||
cache.getCacheTransactionManager().addListener(transactionListener);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private void registerTransactionWriter(Cache cache) {
|
||||
private void registerTransactionWriter(GemFireCache cache) {
|
||||
if (transactionWriter != null) {
|
||||
cache.getCacheTransactionManager().setWriter(transactionWriter);
|
||||
}
|
||||
@@ -514,7 +492,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
if (close) {
|
||||
Cache localCache = (Cache) fetchCache();
|
||||
Cache localCache = fetchCache();
|
||||
|
||||
if (localCache != null && !localCache.isClosed()) {
|
||||
localCache.close();
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.data.gemfire;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.springframework.data.gemfire.config.support.GemfireFeature;
|
||||
import org.springframework.data.gemfire.util.DistributedSystemUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
@@ -27,13 +28,14 @@ import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.internal.GemFireVersion;
|
||||
|
||||
/**
|
||||
* The GemfireUtils class is a utility class encapsulating common functionality to access features and capabilities
|
||||
* GemfireUtils is an abstract utility class encapsulating common functionality to access features and capabilities
|
||||
* of GemFire based on version and other configuration meta-data.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.util.DistributedSystemUtils
|
||||
* @since 1.3.3
|
||||
*/
|
||||
public abstract class GemfireUtils {
|
||||
public abstract class GemfireUtils extends DistributedSystemUtils {
|
||||
|
||||
public final static String GEMFIRE_NAME = GemFireVersion.getProductName();
|
||||
public final static String GEMFIRE_VERSION = CacheFactory.getVersion();
|
||||
|
||||
@@ -22,65 +22,34 @@ import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
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.CollectionUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.Cache;
|
||||
import com.gemstone.gemfire.cache.GemFireCache;
|
||||
import com.gemstone.gemfire.cache.client.ClientCache;
|
||||
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
|
||||
import com.gemstone.gemfire.cache.client.Pool;
|
||||
import com.gemstone.gemfire.cache.client.PoolManager;
|
||||
import com.gemstone.gemfire.distributed.DistributedSystem;
|
||||
import com.gemstone.gemfire.pdx.PdxSerializer;
|
||||
|
||||
/**
|
||||
* FactoryBean dedicated to creating client caches (caches for client JVMs).
|
||||
* Acts an utility class (as client caches are a subset with a particular
|
||||
* configuration of the generic cache).
|
||||
* FactoryBean dedicated to creating GemFire client caches.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Lyndon Adams
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.CacheFactoryBean
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCacheFactory
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ClientCacheFactoryBean extends CacheFactoryBean {
|
||||
|
||||
/**
|
||||
* Inner class to avoid a hard dependency on the GemFire 6.6 API.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
private class PdxOptions implements Runnable {
|
||||
|
||||
private ClientCacheFactory factory;
|
||||
|
||||
private PdxOptions(ClientCacheFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if (pdxSerializer != null) {
|
||||
Assert.isAssignable(PdxSerializer.class, pdxSerializer.getClass(), "Invalid pdx serializer used");
|
||||
factory.setPdxSerializer((PdxSerializer) pdxSerializer);
|
||||
}
|
||||
if (pdxDiskStoreName != null) {
|
||||
factory.setPdxDiskStore(pdxDiskStoreName);
|
||||
}
|
||||
if (pdxIgnoreUnreadFields != null) {
|
||||
factory.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields);
|
||||
}
|
||||
if (pdxPersistent != null) {
|
||||
factory.setPdxPersistent(pdxPersistent);
|
||||
}
|
||||
if (pdxReadSerialized != null) {
|
||||
factory.setPdxReadSerialized(pdxReadSerialized);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected Boolean readyForEvents = false;
|
||||
|
||||
private Pool pool;
|
||||
@@ -91,21 +60,111 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
|
||||
protected void postProcessPropertiesBeforeInitialization(Properties gemfireProperties) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches an existing GemFire ClientCache instance from the ClientCacheFactory.
|
||||
*
|
||||
* @param <T> is Class type extension of GemFireCache.
|
||||
* @return the existing GemFire ClientCache instance if available.
|
||||
* @throws com.gemstone.gemfire.cache.CacheClosedException if an existing GemFire Cache instance does not exist.
|
||||
* @throws java.lang.IllegalStateException if the GemFire cache instance is not a ClientCache.
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCacheFactory#getAnyInstance()
|
||||
*/
|
||||
@Override
|
||||
protected GemFireCache fetchCache() {
|
||||
return ClientCacheFactory.getAnyInstance();
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends GemFireCache> T fetchCache() {
|
||||
return (T) ClientCacheFactory.getAnyInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the GemFire System properties used to configure the GemFire ClientCache instance.
|
||||
*
|
||||
* @return a Properties object containing GemFire System properties used to configure
|
||||
* the GemFire ClientCache instance.
|
||||
*/
|
||||
@Override
|
||||
protected GemFireCache createCache(Object factory) {
|
||||
return initializePool((ClientCacheFactory) factory).create();
|
||||
protected Properties resolveProperties() {
|
||||
Properties gemfireProperties = super.resolveProperties();
|
||||
|
||||
DistributedSystem distributedSystem = getDistributedSystem();
|
||||
|
||||
if (GemfireUtils.isConnected(distributedSystem)) {
|
||||
Properties distributedSystemProperties = (Properties) distributedSystem.getProperties().clone();
|
||||
distributedSystemProperties.putAll(gemfireProperties);
|
||||
gemfireProperties = distributedSystemProperties;
|
||||
}
|
||||
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
<T extends DistributedSystem> T getDistributedSystem() {
|
||||
return GemfireUtils.getDistributedSystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of GemFire factory initialized with the given GemFire System Properties
|
||||
* to create an instance of a GemFire cache.
|
||||
*
|
||||
* @param gemfireProperties a Properties object containing GemFire System properties.
|
||||
* @return an instance of a GemFire factory used to create a GemFire cache instance.
|
||||
* @see java.util.Properties
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCacheFactory
|
||||
*/
|
||||
@Override
|
||||
protected Object createFactory(Properties gemfireProperties) {
|
||||
return new ClientCacheFactory(gemfireProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the GemFire factory used to create the GemFire client cache instance. Sets PDX options
|
||||
* specified by the user.
|
||||
*
|
||||
* @param factory the GemFire factory used to create an instance of the GemFire client cache.
|
||||
* @return the initialized GemFire client cache factory.
|
||||
* @see #isPdxOptionsSpecified()
|
||||
*/
|
||||
@Override
|
||||
protected Object prepareFactory(final Object factory) {
|
||||
if (isPdxOptionsSpecified()) {
|
||||
ClientCacheFactory clientCacheFactory = (ClientCacheFactory) factory;
|
||||
|
||||
if (pdxSerializer != null) {
|
||||
Assert.isAssignable(PdxSerializer.class, pdxSerializer.getClass(), "Invalid pdx serializer used");
|
||||
clientCacheFactory.setPdxSerializer((PdxSerializer) pdxSerializer);
|
||||
}
|
||||
if (pdxDiskStoreName != null) {
|
||||
clientCacheFactory.setPdxDiskStore(pdxDiskStoreName);
|
||||
}
|
||||
if (pdxIgnoreUnreadFields != null) {
|
||||
clientCacheFactory.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields);
|
||||
}
|
||||
if (pdxPersistent != null) {
|
||||
clientCacheFactory.setPdxPersistent(pdxPersistent);
|
||||
}
|
||||
if (pdxReadSerialized != null) {
|
||||
clientCacheFactory.setPdxReadSerialized(pdxReadSerialized);
|
||||
}
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new GemFire cache instance using the provided factory.
|
||||
*
|
||||
* @param <T> parameterized Class type extension of GemFireCache.
|
||||
* @param factory the appropriate GemFire factory used to create a cache instance.
|
||||
* @return an instance of the GemFire cache.
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCacheFactory#create()
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends GemFireCache> T createCache(Object factory) {
|
||||
return (T) initializePool((ClientCacheFactory) factory).create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Pool settings on the ClientCacheFactory.
|
||||
*
|
||||
@@ -113,7 +172,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCacheFactory
|
||||
*/
|
||||
private ClientCacheFactory initializePool(ClientCacheFactory clientCacheFactory) {
|
||||
return initializeClientCacheFactoryPool(clientCacheFactory, resolvePool(this.pool));
|
||||
return initializeClientCacheFactory(clientCacheFactory, resolvePool(this.pool));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,7 +219,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCacheFactory
|
||||
* @see com.gemstone.gemfire.cache.client.Pool
|
||||
*/
|
||||
private ClientCacheFactory initializeClientCacheFactoryPool(ClientCacheFactory clientCacheFactory, Pool pool) {
|
||||
private ClientCacheFactory initializeClientCacheFactory(ClientCacheFactory clientCacheFactory, Pool pool) {
|
||||
if (pool != null) {
|
||||
clientCacheFactory.setPoolFreeConnectionTimeout(pool.getFreeConnectionTimeout());
|
||||
clientCacheFactory.setPoolIdleTimeout(pool.getIdleTimeout());
|
||||
@@ -193,44 +252,37 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
|
||||
return clientCacheFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register for events after Pool and Regions have been created and iff non-durable client...
|
||||
*
|
||||
* @param <T> parameterized Class type extension of GemFireCache.
|
||||
* @param cache the GemFire cache instance to process.
|
||||
* @return the processed cache instance after ready for events.
|
||||
* @throws java.io.IOException if an error occurs during post processing.
|
||||
* @see org.springframework.data.gemfire.CacheFactoryBean#postProcess(com.gemstone.gemfire.cache.GemFireCache)
|
||||
* @see #readyForEvents(com.gemstone.gemfire.cache.GemFireCache)
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCache
|
||||
*/
|
||||
@Override
|
||||
protected void setPdxOptions(Object factory) {
|
||||
if (factory instanceof ClientCacheFactory) {
|
||||
new PdxOptions((ClientCacheFactory) factory).run();
|
||||
}
|
||||
protected <T extends GemFireCache> T postProcess(T cache) throws IOException {
|
||||
return readyForEvents(super.postProcess(cache));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inform the GemFire cluster that this client cache is ready to receive events.
|
||||
*/
|
||||
private void readyForEvents(){
|
||||
ClientCache clientCache = ClientCacheFactory.getAnyInstance();
|
||||
|
||||
private <T extends GemFireCache> T readyForEvents(T clientCache) {
|
||||
if (Boolean.TRUE.equals(getReadyForEvents()) && !clientCache.isClosed()) {
|
||||
try {
|
||||
clientCache.readyForEvents();
|
||||
((ClientCache) clientCache).readyForEvents();
|
||||
}
|
||||
catch (IllegalStateException ignore) {
|
||||
// cannot be called for a non-durable client so exception is thrown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register for events after Pool and Regions have been created and iff non-durable client...
|
||||
*
|
||||
* @param cache the GemFire Cache instance to process.
|
||||
* @return the processed GemFire Cache instance after ready for events.
|
||||
* @throws IOException if an error occurs during post processing.
|
||||
* @see org.springframework.data.gemfire.CacheFactoryBean#postProcess(com.gemstone.gemfire.cache.Cache)
|
||||
* @see #readyForEvents()
|
||||
* @see com.gemstone.gemfire.cache.Cache
|
||||
*/
|
||||
@Override
|
||||
protected Cache postProcess(final Cache cache) throws IOException {
|
||||
Cache localCache = super.postProcess(cache);
|
||||
readyForEvents();
|
||||
return localCache;
|
||||
return clientCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.util;
|
||||
|
||||
import com.gemstone.gemfire.distributed.DistributedSystem;
|
||||
import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
|
||||
|
||||
/**
|
||||
* DistributedSystemUtils is an abstract utility class for working with the GemFire DistributedSystem.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see com.gemstone.gemfire.distributed.DistributedSystem
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public abstract class DistributedSystemUtils {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends DistributedSystem> T getDistributedSystem() {
|
||||
return (T) InternalDistributedSystem.getAnyInstance();
|
||||
}
|
||||
|
||||
public static boolean isConnected(DistributedSystem distributedSystem) {
|
||||
return (distributedSystem != null && distributedSystem.isConnected());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -349,16 +349,14 @@ Defines a GemFire Client Cache instance used for creating or retrieving 'regions
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="cacheBaseType">
|
||||
<xsd:attribute name="pool-name" type="xsd:string"
|
||||
use="optional">
|
||||
<xsd:attribute name="pool-name" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The name of the pool used by this client.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="ready-for-events" type="xsd:string"
|
||||
use="optional" default="false">
|
||||
<xsd:attribute name="ready-for-events" type="xsd:string" use="optional" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Notifies the server that this durable client is ready to receive updates.
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.client;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.gemfire.fork.ServerProcess;
|
||||
import org.springframework.data.gemfire.process.ProcessExecutor;
|
||||
import org.springframework.data.gemfire.process.ProcessWrapper;
|
||||
import org.springframework.data.gemfire.test.support.FileSystemUtils;
|
||||
import org.springframework.data.gemfire.test.support.ThreadUtils;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.gemstone.gemfire.cache.CacheLoader;
|
||||
import com.gemstone.gemfire.cache.CacheLoaderException;
|
||||
import com.gemstone.gemfire.cache.LoaderHelper;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* The ClientCacheSecurityTest class...
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class ClientCacheSecurityTest {
|
||||
|
||||
private static ProcessWrapper serverProcess;
|
||||
|
||||
@Resource(name = "Example")
|
||||
private Region<String, String> example;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() throws IOException {
|
||||
String serverName = "GemFireSecurityCacheServer";
|
||||
|
||||
File serverWorkingDirectory = new File(FileSystemUtils.WORKING_DIRECTORY, serverName.toLowerCase());
|
||||
|
||||
Assert.isTrue(serverWorkingDirectory.isDirectory() || serverWorkingDirectory.mkdirs());
|
||||
|
||||
List<String> arguments = new ArrayList<String>();
|
||||
|
||||
arguments.add(String.format("-Dgemfire.name=%1$s", serverName));
|
||||
arguments.add(String.format("-Djavax.net.ssl.keyStore=%1$s", System.getProperty("javax.net.ssl.keyStore")));
|
||||
arguments.add("/org/springframework/data/gemfire/client/ClientCacheSecurityTest-server-context.xml");
|
||||
|
||||
serverProcess = ProcessExecutor.launch(serverWorkingDirectory, ServerProcess.class,
|
||||
arguments.toArray(new String[arguments.size()]));
|
||||
|
||||
waitForServerStart(TimeUnit.SECONDS.toMillis(20));
|
||||
|
||||
System.out.println("GemFire Cache Server Process for ClientCache Security should be running...");
|
||||
}
|
||||
|
||||
private static void waitForServerStart(final long milliseconds) {
|
||||
ThreadUtils.timedWait(milliseconds, TimeUnit.MILLISECONDS.toMillis(500), new ThreadUtils.WaitCondition() {
|
||||
private File serverPidControlFile = new File(serverProcess.getWorkingDirectory(),
|
||||
ServerProcess.getServerProcessControlFilename());
|
||||
|
||||
@Override public boolean waiting() {
|
||||
return !serverPidControlFile.isFile();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() {
|
||||
serverProcess.shutdown();
|
||||
|
||||
if (Boolean.valueOf(System.getProperty("spring.gemfire.fork.clean", Boolean.TRUE.toString()))) {
|
||||
org.springframework.util.FileSystemUtils.deleteRecursively(serverProcess.getWorkingDirectory());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exampleRegionGet() {
|
||||
assertThat(String.valueOf(example.get("TestKey")), is(equalTo("TestValue")));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static class TestCacheLoader implements CacheLoader<String, String> {
|
||||
|
||||
@Override public String load(final LoaderHelper<String, String> helper) throws CacheLoaderException {
|
||||
return "TestValue";
|
||||
}
|
||||
|
||||
@Override public void close() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
">
|
||||
|
||||
<util:properties id="client.properties">
|
||||
<prop key="client.server.host">localhost</prop>
|
||||
<prop key="client.server.port">31517</prop>
|
||||
<prop key="gemfire.security.ssl.enabled">true</prop>
|
||||
<prop key="gemfire.security.ssl.require-authentication">true</prop>
|
||||
<prop key="gemfire.security.ssl.protocols">any</prop>
|
||||
<prop key="gemfire.security.ssl.ciphers">any</prop>
|
||||
<prop key="gemfire.security.ssl.keystore.location">${javax.net.ssl.keyStore}</prop>
|
||||
<prop key="gemfire.security.ssl.keystore.password">s3cr3t</prop>
|
||||
<prop key="gemfire.security.ssl.keystore.type">jks</prop>
|
||||
</util:properties>
|
||||
|
||||
<context:property-placeholder properties-ref="client.properties" system-properties-mode="FALLBACK"/>
|
||||
|
||||
<util:properties id="gemfireProperties">
|
||||
<prop key="cluster-ssl-enabled">${gemfire.security.ssl.enabled}</prop>
|
||||
<prop key="cluster-ssl-require-authentication">${gemfire.security.ssl.require-authentication}</prop>
|
||||
<prop key="cluster-ssl-protocols">${gemfire.security.ssl.protocols}</prop>
|
||||
<prop key="cluster-ssl-ciphers">${gemfire.security.ssl.ciphers}</prop>
|
||||
<prop key="cluster-ssl-keystore">${gemfire.security.ssl.keystore.location}</prop>
|
||||
<prop key="cluster-ssl-keystore-password">${gemfire.security.ssl.keystore.password}</prop>
|
||||
<prop key="cluster-ssl-keystore-type">${gemfire.security.ssl.keystore.type}</prop>
|
||||
<prop key="cluster-ssl-truststore">${gemfire.security.ssl.keystore.location}</prop>
|
||||
<prop key="cluster-ssl-truststore-password">${gemfire.security.ssl.keystore.password}</prop>
|
||||
<prop key="log-level">warning</prop>
|
||||
<prop key="mcast-port">0</prop>
|
||||
</util:properties>
|
||||
|
||||
<gfe:pool id="gemfireServerPool" max-connections="1" min-connections="1">
|
||||
<gfe:server host="${client.server.host}" port="${client.server.port}"/>
|
||||
</gfe:pool>
|
||||
|
||||
<gfe:client-cache properties-ref="gemfireProperties" pool-name="gemfireServerPool"/>
|
||||
|
||||
<gfe:client-region id="Example" pool-name="gemfireServerPool" shortcut="PROXY"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
">
|
||||
|
||||
<util:properties id="server.properties">
|
||||
<prop key="gemfire.security.ssl.enabled">true</prop>
|
||||
<prop key="gemfire.security.ssl.require-authentication">true</prop>
|
||||
<prop key="gemfire.security.ssl.protocols">any</prop>
|
||||
<prop key="gemfire.security.ssl.ciphers">any</prop>
|
||||
<prop key="gemfire.security.ssl.keystore.location">${javax.net.ssl.keyStore}</prop>
|
||||
<prop key="gemfire.security.ssl.keystore.password">s3cr3t</prop>
|
||||
<prop key="gemfire.security.ssl.keystore.type">jks</prop>
|
||||
<prop key="gemfire.server.host">localhost</prop>
|
||||
<prop key="gemfire.server.port">31517</prop>
|
||||
</util:properties>
|
||||
|
||||
<context:property-placeholder properties-ref="server.properties"/>
|
||||
|
||||
<util:properties id="gemfireProperties">
|
||||
<prop key="name">ClientCacheSecurityTestServer</prop>
|
||||
<prop key="mcast-port">0</prop>
|
||||
<prop key="log-level">warning</prop>
|
||||
<prop key="cluster-ssl-enabled">${gemfire.security.ssl.enabled}</prop>
|
||||
<prop key="cluster-ssl-require-authentication">${gemfire.security.ssl.require-authentication}</prop>
|
||||
<prop key="cluster-ssl-protocols">${gemfire.security.ssl.protocols}</prop>
|
||||
<prop key="cluster-ssl-ciphers">${gemfire.security.ssl.ciphers}</prop>
|
||||
<prop key="cluster-ssl-keystore">${gemfire.security.ssl.keystore.location}</prop>
|
||||
<prop key="cluster-ssl-keystore-password">${gemfire.security.ssl.keystore.password}</prop>
|
||||
<prop key="cluster-ssl-keystore-type">${gemfire.security.ssl.keystore.type}</prop>
|
||||
<prop key="cluster-ssl-truststore">${gemfire.security.ssl.keystore.location}</prop>
|
||||
<prop key="cluster-ssl-truststore-password">${gemfire.security.ssl.keystore.password}</prop>
|
||||
</util:properties>
|
||||
|
||||
<gfe:cache properties-ref="gemfireProperties"/>
|
||||
|
||||
<gfe:cache-server auto-startup="true" bind-address="${gemfire.server.host}" port="${gemfire.server.port}"
|
||||
max-connections="1"/>
|
||||
|
||||
<gfe:replicated-region id="Example" persistent="false">
|
||||
<gfe:cache-loader>
|
||||
<bean class="org.springframework.data.gemfire.client.ClientCacheSecurityTest$TestCacheLoader"/>
|
||||
</gfe:cache-loader>
|
||||
</gfe:replicated-region>
|
||||
|
||||
</beans>
|
||||
BIN
src/test/resources/trusted.keystore
Normal file
BIN
src/test/resources/trusted.keystore
Normal file
Binary file not shown.
Reference in New Issue
Block a user