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:
John Blum
2015-07-09 18:26:21 -07:00
parent e3198c1803
commit 82334090fe
10 changed files with 454 additions and 154 deletions

View File

@@ -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();

View File

@@ -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();

View File

@@ -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

View File

@@ -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());
}
}

View File

@@ -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.

View File

@@ -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() {
}
}
}

View File

@@ -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>

View File

@@ -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>

Binary file not shown.