From 28c799a1777f42130441ad155f2799b5b8c4ddc1 Mon Sep 17 00:00:00 2001 From: John Blum Date: Thu, 9 Jul 2015 18:26:21 -0700 Subject: [PATCH] SGF-414 - Resolve incompatibility between the DistributedSystem created by the PoolFactoryBean and the DistributedSystem resolved by the ClientCacheFactoryBean when SSL is configured. --- build.gradle | 1 + gradle.properties | 18 +- .../data/gemfire/CacheFactoryBean.java | 144 ++++++------- .../data/gemfire/GemfireUtils.java | 6 +- .../client/ClientCacheFactoryBean.java | 196 ++++++++++++------ .../gemfire/util/DistributedSystemUtils.java | 40 ++++ .../gemfire/config/spring-gemfire-1.6.xsd | 6 +- .../client/ClientCacheSecurityTest.java | 125 +++++++++++ .../ClientCacheSecurityTest-context.xml | 50 +++++ ...ClientCacheSecurityTest-server-context.xml | 54 +++++ src/test/resources/trusted.keystore | Bin 0 -> 1135 bytes 11 files changed, 476 insertions(+), 164 deletions(-) create mode 100644 src/main/java/org/springframework/data/gemfire/util/DistributedSystemUtils.java create mode 100644 src/test/java/org/springframework/data/gemfire/client/ClientCacheSecurityTest.java create mode 100644 src/test/resources/org/springframework/data/gemfire/client/ClientCacheSecurityTest-context.xml create mode 100644 src/test/resources/org/springframework/data/gemfire/client/ClientCacheSecurityTest-server-context.xml create mode 100644 src/test/resources/trusted.keystore diff --git a/build.gradle b/build.gradle index 1761b02e..f96b5745 100644 --- a/build.gradle +++ b/build.gradle @@ -52,6 +52,7 @@ if (project.hasProperty('platformVersion')) { tasks.withType(Test).all { forkEvery = 1 systemProperties['gemfire.disableShutdownHook'] = 'true' + systemProperties['javax.net.ssl.keyStore'] = System.getProperty('user.dir') + '/src/test/resources/trusted.keystore' systemProperties['org.springframework.data.gemfire.test.GemfireTestRunner.nomock'] = System.getProperty('org.springframework.data.gemfire.test.GemfireTestRunner.nomock') } diff --git a/gradle.properties b/gradle.properties index cd300318..0fb14583 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,14 +1,14 @@ antlrVersion=2.7.7 -slf4jVersion=1.7.10 -junitVersion=4.12 -gemfireVersion=8.0.0 -spring.range="[4.0.0, 5.0.0)" aspectjVersion=1.8.5 -springDataBuildVersion=1.6.2.BUILD-SNAPSHOT -springVersion=4.0.9.RELEASE -springDataCommonsVersion=1.10.2.BUILD-SNAPSHOT -log4jVersion=1.2.17 +gemfireVersion=8.0.0 hamcrestVersion=1.3 -version=1.6.2.BUILD-SNAPSHOT jacksonVersion=2.5.1 +junitVersion=4.12 +log4jVersion=1.2.17 mockitoVersion=1.10.19 +slf4jVersion=1.7.10 +spring.range="[4.0.0, 5.0.0)" +springVersion=4.0.9.RELEASE +springDataBuildVersion=1.6.2.BUILD-SNAPSHOT +springDataCommonsVersion=1.10.2.BUILD-SNAPSHOT +version=1.6.2.BUILD-SNAPSHOT diff --git a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java index 8e5bf563..e44be6a9 100644 --- a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java @@ -39,7 +39,6 @@ import org.springframework.core.io.Resource; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; import com.gemstone.gemfire.GemFireCheckedException; import com.gemstone.gemfire.GemFireException; @@ -207,40 +206,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() @@ -303,7 +268,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, /** * If Dynamic Regions are enabled, create and initialize a DynamicRegionFactory before creating the Cache. */ - private void initializeDynamicRegionFactory() { + private void initDynamicRegionFactory() { if (dynamicRegionSupport != null) { dynamicRegionSupport.initializeDynamicRegionFactory(); } @@ -317,7 +282,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, * @see com.gemstone.gemfire.cache.Cache * @see #fetchCache() * @see #createFactory(java.util.Properties) - * @see #initializeFactory(Object) + * @see #prepareFactory(Object) * @see #createCache(Object) */ protected Cache resolveCache() { @@ -327,39 +292,40 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, } catch (CacheClosedException ex) { cacheResolutionMessagePrefix = "Created new"; - initializeDynamicRegionFactory(); - return (Cache) createCache(initializeFactory(createFactory(getProperties()))); + initDynamicRegionFactory(); + 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 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 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 @@ -372,19 +338,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 initializeFactory(Object factory) { + 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; } @@ -400,17 +378,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 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 createCache(Object factory) { + return (T) (cache != null ? cache : ((CacheFactory) factory).create()); } /** @@ -422,12 +400,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 postProcess(T cache) throws IOException { Resource localCacheXml = getCacheXml(); // load cache.xml Resource and initialize the Cache @@ -443,19 +421,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); @@ -467,7 +445,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", @@ -484,14 +462,14 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, } /* (non-Javadoc) */ - private void registerTransactionListeners(Cache cache) { + private void registerTransactionListeners(GemFireCache cache) { for (TransactionListener transactionListener : 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); } @@ -515,7 +493,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(); diff --git a/src/main/java/org/springframework/data/gemfire/GemfireUtils.java b/src/main/java/org/springframework/data/gemfire/GemfireUtils.java index 28988444..2c84791a 100644 --- a/src/main/java/org/springframework/data/gemfire/GemfireUtils.java +++ b/src/main/java/org/springframework/data/gemfire/GemfireUtils.java @@ -18,19 +18,21 @@ package org.springframework.data.gemfire; import java.util.concurrent.ConcurrentMap; +import org.springframework.data.gemfire.util.DistributedSystemUtils; import org.springframework.util.ClassUtils; import com.gemstone.gemfire.cache.CacheFactory; import com.gemstone.gemfire.cache.Region; /** - * 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_VERSION = CacheFactory.getVersion(); diff --git a/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java index 90ac33c1..017fa047 100644 --- a/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java @@ -16,11 +16,13 @@ package org.springframework.data.gemfire.client; +import java.io.IOException; import java.net.InetSocketAddress; 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.util.Assert; import org.springframework.util.StringUtils; @@ -30,54 +32,23 @@ 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; @@ -88,28 +59,109 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { protected void postProcessPropertiesBeforeInitialization(Properties gemfireProperties) { } + /** + * Fetches an existing GemFire ClientCache instance from the ClientCacheFactory. + * + * @param 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 createCache(Object factory) { - ClientCacheFactory clientCacheFactory = (ClientCacheFactory) factory; - - initializePool(clientCacheFactory); - - GemFireCache cache = clientCacheFactory.create(); - - // register for events after Pool and Regions been created and iff non-durable client... - readyForEvents(); - - return cache; + @SuppressWarnings("unchecked") + protected 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 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 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 GemFireCache fetchCache() { - return ClientCacheFactory.getAnyInstance(); + 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 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 createCache(Object factory) { + return (T) initializePool((ClientCacheFactory) factory).create(); } /** @@ -118,8 +170,8 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { * @param clientCacheFactory the GemFire ClientCacheFactory used to configure and create a GemFire ClientCache. * @see com.gemstone.gemfire.cache.client.ClientCacheFactory */ - private void initializePool(ClientCacheFactory clientCacheFactory) { - initializeClientCacheFactoryPoolSettings(clientCacheFactory, resolvePool(this.pool)); + private ClientCacheFactory initializePool(ClientCacheFactory clientCacheFactory) { + return initializeClientCacheFactory(clientCacheFactory, resolvePool(this.pool)); } /** @@ -166,7 +218,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { * @see com.gemstone.gemfire.cache.client.ClientCacheFactory * @see com.gemstone.gemfire.cache.client.Pool */ - private void initializeClientCacheFactoryPoolSettings(ClientCacheFactory clientCacheFactory, Pool pool) { + private ClientCacheFactory initializeClientCacheFactory(ClientCacheFactory clientCacheFactory, Pool pool) { if (pool != null) { clientCacheFactory.setPoolFreeConnectionTimeout(pool.getFreeConnectionTimeout()); clientCacheFactory.setPoolIdleTimeout(pool.getIdleTimeout()); @@ -195,34 +247,41 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { clientCacheFactory.addPoolServer(socketAddress.getHostName(), socketAddress.getPort()); } } + + return clientCacheFactory; } + /** + * Register for events after Pool and Regions have been created and iff non-durable client... + * + * @param 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 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(); - - if (Boolean.TRUE.equals(readyForEvents) && !clientCache.isClosed()) { + private 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 } } - } - @Override - public final Boolean getEnableAutoReconnect() { - return Boolean.FALSE; + return clientCache; } @Override @@ -230,6 +289,11 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { throw new UnsupportedOperationException("Auto-reconnect is not supported on ClientCache."); } + @Override + public final Boolean getEnableAutoReconnect() { + return Boolean.FALSE; + } + /** * Sets the pool used by this client. * diff --git a/src/main/java/org/springframework/data/gemfire/util/DistributedSystemUtils.java b/src/main/java/org/springframework/data/gemfire/util/DistributedSystemUtils.java new file mode 100644 index 00000000..57985a79 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/util/DistributedSystemUtils.java @@ -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 getDistributedSystem() { + return (T) InternalDistributedSystem.getAnyInstance(); + } + + public static boolean isConnected(DistributedSystem distributedSystem) { + return (distributedSystem != null && distributedSystem.isConnected()); + } + +} diff --git a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.6.xsd b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.6.xsd index ef6ec09e..a0eb7491 100644 --- a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.6.xsd +++ b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.6.xsd @@ -349,16 +349,14 @@ Defines a GemFire Client Cache instance used for creating or retrieving 'regions - + - + 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 arguments = new ArrayList(); + + 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 { + + @Override public String load(final LoaderHelper helper) throws CacheLoaderException { + return "TestValue"; + } + + @Override public void close() { + } + } + +} diff --git a/src/test/resources/org/springframework/data/gemfire/client/ClientCacheSecurityTest-context.xml b/src/test/resources/org/springframework/data/gemfire/client/ClientCacheSecurityTest-context.xml new file mode 100644 index 00000000..62f35e4f --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/client/ClientCacheSecurityTest-context.xml @@ -0,0 +1,50 @@ + + + + + localhost + 31517 + true + true + any + any + ${javax.net.ssl.keyStore} + s3cr3t + jks + + + + + + ${gemfire.security.ssl.enabled} + ${gemfire.security.ssl.require-authentication} + ${gemfire.security.ssl.protocols} + ${gemfire.security.ssl.ciphers} + ${gemfire.security.ssl.keystore.location} + ${gemfire.security.ssl.keystore.password} + ${gemfire.security.ssl.keystore.type} + ${gemfire.security.ssl.keystore.location} + ${gemfire.security.ssl.keystore.password} + warning + 0 + + + + + + + + + + + diff --git a/src/test/resources/org/springframework/data/gemfire/client/ClientCacheSecurityTest-server-context.xml b/src/test/resources/org/springframework/data/gemfire/client/ClientCacheSecurityTest-server-context.xml new file mode 100644 index 00000000..35e26b75 --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/client/ClientCacheSecurityTest-server-context.xml @@ -0,0 +1,54 @@ + + + + + true + true + any + any + ${javax.net.ssl.keyStore} + s3cr3t + jks + localhost + 31517 + + + + + + ClientCacheSecurityTestServer + 0 + warning + ${gemfire.security.ssl.enabled} + ${gemfire.security.ssl.require-authentication} + ${gemfire.security.ssl.protocols} + ${gemfire.security.ssl.ciphers} + ${gemfire.security.ssl.keystore.location} + ${gemfire.security.ssl.keystore.password} + ${gemfire.security.ssl.keystore.type} + ${gemfire.security.ssl.keystore.location} + ${gemfire.security.ssl.keystore.password} + + + + + + + + + + + + + diff --git a/src/test/resources/trusted.keystore b/src/test/resources/trusted.keystore new file mode 100644 index 0000000000000000000000000000000000000000..c6affdb67a8ce3dab6f3d3f4a4e7dafca8a4fa26 GIT binary patch literal 1135 zcmezO_TO6u1_mY|W&~sQ^wiw6%%W5v-!FA<`!XQiZ_vcpZNSIIrOn33!l=b0$jHdb zz|zE6-nL5f&w~CJj2tE*YzI;%YwN6Vzv?vQ=kNI3^^f^pJVcalOn3UX{R__8ax zjXEFqKdU%xcmL{<vLB5itcAK3QCWMl~he;dr@YUwEB?3iW`1Ays#CwCU(xOy=wBp{p?hG_NCSv z?e#zZ=q9kv1_$?oU>qIW@RvtF_bcpU}FwtVHOt5O3EqC)y+*RD9YE% z$xlwqF_07IH8eFaH!w3YHnuc1ivn`ZfLv23mw@gj#_hn=p#!sy5y+8eYHVcqTOZsg zTPma(bl+=^-kT@SzX@&+vU%^qa9Ga1VOyYDrfaN&QsD1M+un#@`;UIzW$^9v?9iO+ zjn)maCi$Pz61Hd03|P8k{`?m#)dEU~{CBUs{%`v+=^xhN&yTHGCd$w9yZPJYqjHCt zOhbgD#3mYjEB(AqJMp^K`%g;Dl5;P5FdkKL;f;X5m*tl$01>Q&Rva35}4_NMf}$nd^hS0eqN6|xI7Hf-?} zD^z~rqah}|{XC~p&xvIZZN#d&Luz_89xPrbr@eVu>BPLn_1wP{O_M(UPO4&5u|Bip zQL1bMjz{c=RLKU8(SEd8XG+Qt{8LKuD`|*XVoaN-S8Q#*d6Uc8^_eL* zP?8a|K7)Y{lZcB0TTj#XjaPNW|9Nn!q`ePGNV~!$qP6hyf75>lZ@)UkQ0>L_eWHl& bBwv%H2W{*&j7^^tZoK{==6*4#Ufl`+`B>v< literal 0 HcmV?d00001