From 56054f2987045dcbb0490e3e49a576f00628796f Mon Sep 17 00:00:00 2001 From: John Blum Date: Mon, 23 Mar 2015 18:05:41 -0700 Subject: [PATCH] SGF-385 - Local region does remote put in addition to local put in client cache. --- .../data/gemfire/CacheFactoryBean.java | 398 +++++++++------ .../client/ClientCacheFactoryBean.java | 192 ++++---- .../client/ClientRegionFactoryBean.java | 61 +-- .../data/gemfire/client/PoolFactoryBean.java | 454 +++++++----------- .../data/gemfire/config/GemfireConstants.java | 8 +- .../data/gemfire/config/PoolParser.java | 36 +- .../data/gemfire/client/ClientCacheTest.java | 3 +- .../client/ClientRegionFactoryBeanTest.java | 192 +++++++- .../gemfire/config/CacheNamespaceTest.java | 49 +- .../gemfire/config/PoolNamespaceTest.java | 56 ++- .../gemfire/test/MockCacheFactoryBean.java | 5 +- .../test/MockClientCacheFactoryBean.java | 5 +- .../resources/clientcache-with-regions.xml | 3 - .../data/gemfire/client/client-cache.xml | 33 +- .../FunctionIntegrationTests-context.xml | 19 +- 15 files changed, 859 insertions(+), 655 deletions(-) diff --git a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java index ea8ccaf4..839caa39 100644 --- a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java @@ -17,7 +17,9 @@ package org.springframework.data.gemfire; import java.io.File; +import java.io.IOException; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -38,7 +40,6 @@ import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.CollectionUtils; import com.gemstone.gemfire.GemFireCheckedException; import com.gemstone.gemfire.GemFireException; @@ -58,24 +59,32 @@ import com.gemstone.gemfire.pdx.PdxSerializable; import com.gemstone.gemfire.pdx.PdxSerializer; /** - * Factory used for configuring a Gemfire Cache manager. Allows either retrieval - * of an existing, opened cache or the creation of a new one. - * + * FactoryBean used for configuring a Gemfire Cache instance. Allows either the retrieval of an existing + * opened Cache instance or the creation of a new Cache instance. *

* This class implements the * {@link org.springframework.dao.support.PersistenceExceptionTranslator} * interface, as auto-detected by Spring's - * {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor} - * , for AOP-based translation of native exceptions to Spring - * DataAccessExceptions. Hence, the presence of this class automatically enables - * a PersistenceExceptionTranslationPostProcessor to translate GemFire - * exceptions. + * {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor}, + * for AOP-based translation of native exceptions to Spring DataAccessExceptions. Hence, the presence + * of this class automatically enables a PersistenceExceptionTranslationPostProcessor to translate GemFire Exceptions. * * @author Costin Leau * @author David Turanski + * @author John Blum + * @see org.springframework.beans.factory.BeanClassLoaderAware + * @see org.springframework.beans.factory.BeanFactoryAware + * @see org.springframework.beans.factory.BeanNameAware + * @see org.springframework.beans.factory.DisposableBean + * @see org.springframework.beans.factory.FactoryBean + * @see org.springframework.beans.factory.InitializingBean + * @see org.springframework.dao.support.PersistenceExceptionTranslator + * @see com.gemstone.gemfire.cache.Cache + * @see com.gemstone.gemfire.cache.CacheFactory */ -public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanClassLoaderAware, InitializingBean, - DisposableBean, FactoryBean, PersistenceExceptionTranslator { +@SuppressWarnings("unused") +public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, BeanNameAware, FactoryBean, + InitializingBean, DisposableBean, PersistenceExceptionTranslator { protected static final List VALID_JNDI_DATASOURCE_TYPE_NAMES = Collections.unmodifiableList( Arrays.asList("ManagedDataSource", "PooledDataSource", "SimpleDataSource", "XAPooledDataSource")); @@ -102,7 +111,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl protected Float criticalHeapPercentage; protected Float evictionHeapPercentage; - protected GemfireBeanFactoryLocator factoryLocator; + protected GemfireBeanFactoryLocator beanFactoryLocator; protected Integer lockLease; protected Integer lockTimeout; @@ -122,12 +131,13 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl protected Resource cacheXml; protected String beanName; + private String cacheResolutionMessagePrefix; protected String pdxDiskStoreName; protected TransactionWriter transactionWriter; public static class DynamicRegionSupport { - private String diskDir; + private String diskDirectory; private String poolName; @@ -136,11 +146,11 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl private Boolean registerInterest = Boolean.TRUE; public String getDiskDir() { - return diskDir; + return diskDirectory; } public void setDiskDir(String diskDir) { - this.diskDir = diskDir; + this.diskDirectory = diskDir; } public Boolean getPersistent() { @@ -168,12 +178,11 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl } public void initializeDynamicRegionFactory() { - DynamicRegionFactory.Config config = null; - if (diskDir == null) { - config = new DynamicRegionFactory.Config(null, poolName, persistent, registerInterest); - } else { - config = new DynamicRegionFactory.Config(new File(diskDir), poolName, persistent, registerInterest); - } + File localDiskDirectory = (this.diskDirectory == null ? null : new File(this.diskDirectory)); + + DynamicRegionFactory.Config config = new DynamicRegionFactory.Config(localDiskDirectory, poolName, + persistent, registerInterest); + DynamicRegionFactory.get().open(config); } } @@ -210,7 +219,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl private final CacheFactory factory; - PdxOptions(CacheFactory factory) { + private PdxOptions(CacheFactory factory) { this.factory = factory; } @@ -235,111 +244,61 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl } } - private void init() throws Exception { - if (useBeanFactoryLocator && factoryLocator == null) { - factoryLocator = new GemfireBeanFactoryLocator(); - factoryLocator.setBeanFactory(beanFactory); - factoryLocator.setBeanName(beanName); - factoryLocator.afterPropertiesSet(); + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ + @Override + public void afterPropertiesSet() throws Exception { + postProcessPropertiesBeforeInitialization(getProperties()); + + if (!isLazyInitialize()) { + init(); + } + } + + /* (non-Javadoc) */ + protected void postProcessPropertiesBeforeInitialization(Properties gemfireProperties) { + } + + /* (non-Javadoc) */ + private Cache init() throws Exception { + if (useBeanFactoryLocator && beanFactoryLocator == null) { + beanFactoryLocator = new GemfireBeanFactoryLocator(); + beanFactoryLocator.setBeanFactory(beanFactory); + beanFactoryLocator.setBeanName(beanName); + beanFactoryLocator.afterPropertiesSet(); } final ClassLoader originalThreadContextClassLoader = Thread.currentThread().getContextClassLoader(); try { - String messagePrefix; - - // use bean ClassLoader to load GemFire Declarable classes + // use bean ClassLoader to load Spring configured, GemFire Declarable classes Thread.currentThread().setContextClassLoader(beanClassLoader); - try { - cache = (Cache) fetchCache(); - messagePrefix = "Retrieved existing"; - } - catch (CacheClosedException ex) { - initializeDynamicRegionFactory(); - - Object factory = createFactory(this.properties); - - // GemFire 6.6 specific options - if (isPdxSettingsSpecified()) { - Assert.isTrue(ClassUtils.isPresent("com.gemstone.gemfire.pdx.PdxSerializer", beanClassLoader), - "Cannot set PDX options since GemFire 6.6 not detected."); - applyPdxOptions(factory); - } - - // fall back to cache creation - cache = (Cache) createCache(factory); - messagePrefix = "Created new"; - } - - if (this.copyOnRead != null) { - cache.setCopyOnRead(this.copyOnRead); - } - if (lockLease != null) { - cache.setLockLease(lockLease); - } - if (lockTimeout != null) { - cache.setLockTimeout(lockTimeout); - } - if (searchTimeout != null) { - cache.setSearchTimeout(searchTimeout); - } - if (messageSyncInterval != null) { - cache.setMessageSyncInterval(messageSyncInterval); - } - if (gatewayConflictResolver != null) { - cache.setGatewayConflictResolver((GatewayConflictResolver) gatewayConflictResolver); - } + this.cache = postProcess(resolveCache()); DistributedSystem system = cache.getDistributedSystem(); DistributedMember member = system.getDistributedMember(); - log.info(String.format("Connected to Distributed System [%1$s] as Member [%2$s] on Host [%3$s].", - system.getName(), member.getId(), member.getHost())); + log.info(String.format("Connected to Distributed System [%1$s] as Member [%2$s]" + .concat("in Group(s) [%3$s] with Role(s) [%4$s] on Host [%5$s] having PID [%6$d]."), + system.getName(), member.getId(), member.getGroups(), member.getRoles(), member.getHost(), + member.getProcessId())); - log.info(String.format("%1$s GemFire v.%2$s Cache [%3$s].", messagePrefix, CacheFactory.getVersion(), - cache.getName())); + log.info(String.format("%1$s GemFire v.%2$s Cache [%3$s].", cacheResolutionMessagePrefix, + CacheFactory.getVersion(), cache.getName())); - // load/init cache.xml - if (cacheXml != null) { - cache.loadCacheXml(cacheXml.getInputStream()); - - if (log.isDebugEnabled()) { - log.debug("Initialized cache from " + cacheXml); - } - } - - setHeapPercentages(); - registerTransactionListeners(); - registerTransactionWriter(); - registerJndiDataSources(); + return cache; } finally { Thread.currentThread().setContextClassLoader(originalThreadContextClassLoader); } } - private boolean isPdxSettingsSpecified() { - return (pdxSerializer != null || pdxPersistent != null || pdxReadSerialized != null - || pdxIgnoreUnreadFields != null || pdxDiskStoreName != null); - } - /** - * Sets the PDX properties for the given object. Note this is implementation - * specific as it depends on the type of the factory passed in. - * - * @param factory the GemFire CacheFactory used to apply the PDX configuration settings. - */ - protected void applyPdxOptions(Object factory) { - if (factory instanceof CacheFactory) { - new PdxOptions((CacheFactory) factory).run(); - } - } - - /** - * If dynamic regions are enabled, create a DynamicRegionFactory before - * creating the cache + * If Dynamic Regions are enabled, create and initialize a DynamicRegionFactory before creating the Cache. */ private void initializeDynamicRegionFactory() { if (dynamicRegionSupport != null) { @@ -348,82 +307,219 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl } /** - * Register all declared transaction listeners + * Resolves the GemFire Cache by first attempting to lookup and find an existing Cache instance in the VM; + * if an existing Cache could not be found, then this method proceeds in attempting to create a new Cache instance. + * + * @return the resolved GemFire Cache instance. + * @see com.gemstone.gemfire.cache.Cache + * @see #fetchCache() + * @see #createFactory(java.util.Properties) + * @see #initializeFactory(Object) + * @see #createCache(Object) */ - protected void registerTransactionListeners() { - if (!CollectionUtils.isEmpty(transactionListeners)) { - for (TransactionListener transactionListener : transactionListeners) { - cache.getCacheTransactionManager().addListener(transactionListener); - } + protected Cache resolveCache() { + try { + cacheResolutionMessagePrefix = "Found existing"; + return (Cache) fetchCache(); + } + catch (CacheClosedException ex) { + cacheResolutionMessagePrefix = "Created new"; + initializeDynamicRegionFactory(); + return (Cache) createCache(initializeFactory(createFactory(getProperties()))); } } /** - * Register a transaction writer if declared + * Fetches the GemFire Cache by looking up any existing GemFire Cache instance. + * + * @return the existing GemFire Cache instance if available. + * @see com.gemstone.gemfire.cache.GemFireCache + * @see com.gemstone.gemfire.cache.CacheFactory#getAnyInstance() */ - protected void registerTransactionWriter() { - if (transactionWriter != null) { - cache.getCacheTransactionManager().setWriter(transactionWriter); + protected GemFireCache fetchCache() { + return (cache != null ? cache : CacheFactory.getAnyInstance()); + } + + /** + * Creates a new GemFire cache instance using the provided factory. + * + * @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 GemFireCache createCache(Object factory) { + return (cache != null ? cache : ((CacheFactory) factory).create()); + } + + /** + * Creates an instance of GemFire factory initialized with the given GemFire System Properties + * to create an instance of the 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.CacheFactory + */ + protected Object createFactory(Properties gemfireProperties) { + return new CacheFactory(gemfireProperties); + } + + /** + * 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) + */ + protected Object initializeFactory(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); + } + + return factory; + } + + /** + * Determines whether the user specified PDX options. + * + * @return a boolean value indicating whether the user specified PDX options or not. + */ + protected boolean isPdxOptionsSpecified() { + return (pdxSerializer != null || pdxReadSerialized != null || pdxPersistent != null + || pdxIgnoreUnreadFields != null || pdxDiskStoreName != null); + } + + /** + * 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. + * + * @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 + */ + protected void setPdxOptions(Object factory) { + if (factory instanceof CacheFactory) { + new PdxOptions((CacheFactory) factory).run(); } } - private void registerJndiDataSources() { - if (jndiDataSources != null) { - for (JndiDataSource jndiDataSource : jndiDataSources) { - validate(jndiDataSource); - JNDIInvoker.mapDatasource(jndiDataSource.getAttributes(), jndiDataSource.getProps()); + /** + * Post processes the GemFire Cache instance by loading any cache.xml, applying settings specified in SDG XML + * configuration meta-data, and registering the appropriate Transaction Listeners, Writer and JNDI settings. + * + * @param cache the GemFire Cache instance to process. + * @return the GemFire Cache instance after processing. + * @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 #registerJndiDataSources() + */ + protected Cache postProcess(Cache cache) throws IOException { + Resource localCacheXml = getCacheXml(); + + // load cache.xml Resource and initialize the Cache + if (localCacheXml != null) { + if (log.isDebugEnabled()) { + log.debug(String.format("initializing Cache with '%1$s'", cacheXml)); } + + cache.loadCacheXml(localCacheXml.getInputStream()); } + + if (this.copyOnRead != null) { + cache.setCopyOnRead(this.copyOnRead); + } + if (gatewayConflictResolver != null) { + cache.setGatewayConflictResolver((GatewayConflictResolver) gatewayConflictResolver); + } + if (lockLease != null) { + cache.setLockLease(lockLease); + } + if (lockTimeout != null) { + cache.setLockTimeout(lockTimeout); + } + if (messageSyncInterval != null) { + cache.setMessageSyncInterval(messageSyncInterval); + } + if (searchTimeout != null) { + cache.setSearchTimeout(searchTimeout); + } + + setHeapPercentages(cache); + registerTransactionListeners(cache); + registerTransactionWriter(cache); + registerJndiDataSources(); + + return cache; } - private void validate(final JndiDataSource jndiDataSource) { - Map attributes = jndiDataSource.getAttributes(); - String typeAttributeValue = attributes.get("type"); - Assert.isTrue(VALID_JNDI_DATASOURCE_TYPE_NAMES.contains(typeAttributeValue), - String.format("The 'jndi-binding', 'type' [%1$s] is invalid; the 'type' must be one of %2$s.", - typeAttributeValue, VALID_JNDI_DATASOURCE_TYPE_NAMES)); - } - - private void setHeapPercentages() { + /* (non-Javadoc) */ + private void setHeapPercentages(Cache cache) { if (criticalHeapPercentage != null) { Assert.isTrue(criticalHeapPercentage > 0.0 && criticalHeapPercentage <= 100.0, - String.format("Invalid value specified for 'criticalHeapPercentage' (%1$s). Must be > 0.0 and <= 100.0.", + String.format("'criticalHeapPercentage' (%1$s) is invalid; must be > 0.0 and <= 100.0", criticalHeapPercentage)); cache.getResourceManager().setCriticalHeapPercentage(criticalHeapPercentage); } if (evictionHeapPercentage != null) { Assert.isTrue(evictionHeapPercentage > 0.0 && evictionHeapPercentage <= 100.0, - String.format("Invalid value specified for 'evictionHeapPercentage' (%1$s). Must be > 0.0 and <= 100.0.", + String.format("'evictionHeapPercentage' (%1$s) is invalid; must be > 0.0 and <= 100.0", evictionHeapPercentage)); cache.getResourceManager().setEvictionHeapPercentage(evictionHeapPercentage); } } - protected GemFireCache createCache(Object factory) { - return (cache != null ? cache : ((CacheFactory) factory).create()); + /* (non-Javadoc) */ + private void registerTransactionListeners(Cache cache) { + for (TransactionListener transactionListener : nullSafeCollection(transactionListeners)) { + cache.getCacheTransactionManager().addListener(transactionListener); + } } - protected GemFireCache fetchCache() { - return (cache != null ? cache : CacheFactory.getAnyInstance()); + /* (non-Javadoc) */ + private void registerTransactionWriter(Cache cache) { + if (transactionWriter != null) { + cache.getCacheTransactionManager().setWriter(transactionWriter); + } } - protected Object createFactory(Properties props) { - return new CacheFactory(props); + /* (non-Javadoc) */ + private void registerJndiDataSources() { + for (JndiDataSource jndiDataSource : nullSafeCollection(jndiDataSources)) { + String typeAttributeValue = jndiDataSource.getAttributes().get("type"); + Assert.isTrue(VALID_JNDI_DATASOURCE_TYPE_NAMES.contains(typeAttributeValue), + String.format("'jndi-binding' 'type' [%1$s] is invalid; 'type' must be one of %2$s", + typeAttributeValue, VALID_JNDI_DATASOURCE_TYPE_NAMES)); + JNDIInvoker.mapDatasource(jndiDataSource.getAttributes(), jndiDataSource.getProps()); + } + } + + protected Collection nullSafeCollection(final Collection collection) { + return (collection != null ? collection : Collections.emptyList()); } @Override public void destroy() throws Exception { if (close) { - if (cache != null && !cache.isClosed()) { - cache.close(); + Cache localCache = (Cache) fetchCache(); + + if (localCache != null && !localCache.isClosed()) { + localCache.close(); } - cache = null; + this.cache = null; - if (factoryLocator != null) { - factoryLocator.destroy(); - factoryLocator = null; + if (beanFactoryLocator != null) { + beanFactoryLocator.destroy(); + beanFactoryLocator = null; } } } @@ -452,8 +548,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl @Override public Cache getObject() throws Exception { - init(); - return cache; + return init(); } @Override @@ -852,7 +947,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl * @return the beanFactoryLocator */ public GemfireBeanFactoryLocator getBeanFactoryLocator() { - return factoryLocator; + return beanFactoryLocator; } /** @@ -864,13 +959,4 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl return lazyInitialize; } - /* (non-Javadoc) - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() throws Exception { - if (!lazyInitialize) { - init(); - } - } } 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 5f16be45..a039de44 100644 --- a/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java @@ -17,7 +17,6 @@ package org.springframework.data.gemfire.client; import java.net.InetSocketAddress; -import java.util.List; import java.util.Properties; import org.springframework.beans.factory.BeanInitializationException; @@ -42,25 +41,25 @@ import com.gemstone.gemfire.pdx.PdxSerializer; * @author Lyndon Adams * @author John Blum */ +@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; - PdxOptions(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"); + Assert.isAssignable(PdxSerializer.class, pdxSerializer.getClass(), "Invalid pdx serializer used"); factory.setPdxSerializer((PdxSerializer) pdxSerializer); } if (pdxDiskStoreName != null) { @@ -75,120 +74,136 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { if (pdxReadSerialized != null) { factory.setPdxReadSerialized(pdxReadSerialized); } - + } } - private String poolName; - private Pool pool; - protected Boolean readyForEvents = false; + private Pool pool; + + private String poolName; + + @Override + protected void postProcessPropertiesBeforeInitialization(Properties gemfireProperties) { + } + @Override protected GemFireCache createCache(Object factory) { - ClientCacheFactory ccf = (ClientCacheFactory) factory; - initializePool(ccf); - - // Now create the cache - GemFireCache cache = ccf.create(); - - // Register for events after pool/regions been created and iff non-durable client + 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 the cache + return cache; } @Override - protected Object createFactory(Properties props) { - return new ClientCacheFactory(props); + protected Object createFactory(Properties gemfireProperties) { + return new ClientCacheFactory(gemfireProperties); } @Override protected GemFireCache fetchCache() { return ClientCacheFactory.getAnyInstance(); } - - public Properties getProperties() { - return this.properties; + + /** + * Initialize the Pool settings on the ClientCacheFactory. + * + * @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 void initializePool(ClientCacheFactory ccf) { - Pool p = pool; + /** + * Resolves the appropriate GemFire Pool from configuration used to configure the ClientCache. + * + * @param pool the preferred GemFire Pool to use in the configuration of the ClientCache. + * @return the resolved GemFire Pool. + * @see com.gemstone.gemfire.cache.client.Pool + * @see com.gemstone.gemfire.cache.client.PoolManager#find(String) + */ + private Pool resolvePool(final Pool pool) { + Pool localPool = pool; - if (p == null) { - if (StringUtils.hasText(poolName)) { - p = PoolManager.find(poolName); - } - - // Bind this client cache to a pool that hasn't been created yet. - if (p == null) { - PoolFactoryBean.connectToTemporaryDs(this.properties); - } - - if (StringUtils.hasText(poolName)) { + if (localPool == null) { + localPool = PoolManager.find(poolName); + + if (localPool == null) { try { - - getBeanFactory().isTypeMatch(poolName, Pool.class); - } catch (Exception e) { - String msg = "No bean found with name " + poolName - + " of type " + Pool.class.getName(); - if (poolName - .equals(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME)) { - msg += ". A client cache requires a pool"; + if (StringUtils.hasText(poolName) && getBeanFactory().isTypeMatch(poolName, Pool.class)) { + localPool = getBeanFactory().getBean(poolName, Pool.class); + } + else { + localPool = getBeanFactory().getBean(Pool.class); + this.poolName = localPool.getName(); } - throw new BeanInitializationException(msg); } - p = getBeanFactory().getBean(poolName, Pool.class); - } else { - if (log.isDebugEnabled()) { - log.debug("Checking for a unique pool"); + catch (Exception e) { + throw new BeanInitializationException(String.format( + "No bean of type '%1$s' having name '%2$s' was found.%3$s", Pool.class.getName(), poolName, + (GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME.equals(poolName) + ? " A client cache requires a pool." : "")), e); } - p = getBeanFactory().getBean(Pool.class); - this.poolName = p.getName(); } - } - if (p != null) { - // copy the pool settings - this way if the pool is not found, at - // least the cache will have a similar config - ccf.setPoolFreeConnectionTimeout(p.getFreeConnectionTimeout()); - ccf.setPoolIdleTimeout(p.getIdleTimeout()); - ccf.setPoolLoadConditioningInterval(p.getLoadConditioningInterval()); - ccf.setPoolMaxConnections(p.getMaxConnections()); - ccf.setPoolMinConnections(p.getMinConnections()); - ccf.setPoolMultiuserAuthentication(p.getMultiuserAuthentication()); - ccf.setPoolPingInterval(p.getPingInterval()); - ccf.setPoolPRSingleHopEnabled(p.getPRSingleHopEnabled()); - ccf.setPoolReadTimeout(p.getReadTimeout()); - ccf.setPoolRetryAttempts(p.getRetryAttempts()); - ccf.setPoolServerGroup(p.getServerGroup()); - ccf.setPoolSocketBufferSize(p.getSocketBufferSize()); - ccf.setPoolStatisticInterval(p.getStatisticInterval()); - ccf.setPoolSubscriptionAckInterval(p.getSubscriptionAckInterval()); - ccf.setPoolSubscriptionEnabled(p.getSubscriptionEnabled()); - ccf.setPoolSubscriptionMessageTrackingTimeout(p - .getSubscriptionMessageTrackingTimeout()); - ccf.setPoolSubscriptionRedundancy(p.getSubscriptionRedundancy()); - ccf.setPoolThreadLocalConnections(p.getThreadLocalConnections()); + return localPool; + } - List locators = p.getLocators(); - if (locators != null) { - for (InetSocketAddress inet : locators) { - ccf.addPoolLocator(inet.getHostName(), inet.getPort()); - } + /** + * Copy the Pool settings to the ClientCacheFactory so the ClientCache will have a matching configuration. + * + * @param clientCacheFactory the GemFire ClientCacheFactory used to create an instance of the ClientCache. + * @param pool the GemFire Pool from which to copy the pool settings. + * @see com.gemstone.gemfire.cache.client.ClientCacheFactory + * @see com.gemstone.gemfire.cache.client.Pool + */ + private void initializeClientCacheFactoryPoolSettings(ClientCacheFactory clientCacheFactory, Pool pool) { + if (pool != null) { + clientCacheFactory.setPoolFreeConnectionTimeout(pool.getFreeConnectionTimeout()); + clientCacheFactory.setPoolIdleTimeout(pool.getIdleTimeout()); + clientCacheFactory.setPoolLoadConditioningInterval(pool.getLoadConditioningInterval()); + clientCacheFactory.setPoolMaxConnections(pool.getMaxConnections()); + clientCacheFactory.setPoolMinConnections(pool.getMinConnections()); + clientCacheFactory.setPoolMultiuserAuthentication(pool.getMultiuserAuthentication()); + clientCacheFactory.setPoolPingInterval(pool.getPingInterval()); + clientCacheFactory.setPoolPRSingleHopEnabled(pool.getPRSingleHopEnabled()); + clientCacheFactory.setPoolReadTimeout(pool.getReadTimeout()); + clientCacheFactory.setPoolRetryAttempts(pool.getRetryAttempts()); + clientCacheFactory.setPoolServerGroup(pool.getServerGroup()); + clientCacheFactory.setPoolSocketBufferSize(pool.getSocketBufferSize()); + clientCacheFactory.setPoolStatisticInterval(pool.getStatisticInterval()); + clientCacheFactory.setPoolSubscriptionAckInterval(pool.getSubscriptionAckInterval()); + clientCacheFactory.setPoolSubscriptionEnabled(pool.getSubscriptionEnabled()); + clientCacheFactory.setPoolSubscriptionMessageTrackingTimeout(pool.getSubscriptionMessageTrackingTimeout()); + clientCacheFactory.setPoolSubscriptionRedundancy(pool.getSubscriptionRedundancy()); + clientCacheFactory.setPoolThreadLocalConnections(pool.getThreadLocalConnections()); + + for (InetSocketAddress socketAddress : nullSafeCollection(pool.getLocators())) { + clientCacheFactory.addPoolLocator(socketAddress.getHostName(), socketAddress.getPort()); } - List servers = p.getServers(); - if (servers != null) { - for (InetSocketAddress inet : servers) { - ccf.addPoolServer(inet.getHostName(), inet.getPort()); - } + for (InetSocketAddress socketAddress : nullSafeCollection(pool.getServers())) { + clientCacheFactory.addPoolServer(socketAddress.getHostName(), socketAddress.getPort()); } } } + @Override + protected void setPdxOptions(Object factory) { + if (factory instanceof ClientCacheFactory) { + new PdxOptions((ClientCacheFactory) factory).run(); + } + } + /** * Inform the GemFire cluster that this client cache is ready to receive events. */ @@ -200,7 +215,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { clientCache.readyForEvents(); } catch (IllegalStateException ignore) { - // Cannot be called for a non-durable client so exception is thrown. + // cannot be called for a non-durable client so exception is thrown } } } @@ -239,12 +254,5 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { public Boolean getReadyForEvents(){ return this.readyForEvents; } - - @Override - protected void applyPdxOptions(Object factory) { - if (factory instanceof ClientCacheFactory) { - new PdxOptions((ClientCacheFactory) factory).run(); - } - } } diff --git a/src/main/java/org/springframework/data/gemfire/client/ClientRegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/client/ClientRegionFactoryBean.java index 49990194..0a38c0c7 100644 --- a/src/main/java/org/springframework/data/gemfire/client/ClientRegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/ClientRegionFactoryBean.java @@ -25,6 +25,7 @@ import org.springframework.beans.factory.DisposableBean; import org.springframework.core.io.Resource; import org.springframework.data.gemfire.DataPolicyConverter; import org.springframework.data.gemfire.RegionLookupFactoryBean; +import org.springframework.data.gemfire.config.GemfireConstants; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -93,60 +94,58 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean protected Region lookupFallback(GemFireCache cache, String regionName) throws Exception { Assert.isTrue(cache instanceof ClientCache, String.format("Unable to create regions from %1$s", cache)); - // TODO reference to an internal GemFire class! if (cache instanceof GemFireCacheImpl) { Assert.isTrue(((GemFireCacheImpl) cache).isClient(), "A client-cache instance is required."); } ClientCache clientCache = (ClientCache) cache; - ClientRegionFactory factory = clientCache.createClientRegionFactory(resolveClientRegionShortcut()); + ClientRegionFactory clientRegionFactory = clientCache.createClientRegionFactory(resolveClientRegionShortcut()); // map region attributes onto the client region factory if (attributes != null) { - factory.setCloningEnabled(attributes.getCloningEnabled()); - factory.setConcurrencyChecksEnabled(attributes.getConcurrencyChecksEnabled()); - factory.setConcurrencyLevel(attributes.getConcurrencyLevel()); - factory.setCustomEntryIdleTimeout(attributes.getCustomEntryIdleTimeout()); - factory.setCustomEntryTimeToLive(attributes.getCustomEntryTimeToLive()); - factory.setDiskStoreName(attributes.getDiskStoreName()); - factory.setDiskSynchronous(attributes.isDiskSynchronous()); - factory.setEntryIdleTimeout(attributes.getEntryIdleTimeout()); - factory.setEntryTimeToLive(attributes.getEntryTimeToLive()); - factory.setEvictionAttributes(attributes.getEvictionAttributes()); - factory.setInitialCapacity(attributes.getInitialCapacity()); - factory.setKeyConstraint(attributes.getKeyConstraint()); - factory.setLoadFactor(attributes.getLoadFactor()); - factory.setPoolName(attributes.getPoolName()); - factory.setRegionIdleTimeout(attributes.getRegionIdleTimeout()); - factory.setRegionTimeToLive(attributes.getRegionTimeToLive()); - factory.setStatisticsEnabled(attributes.getStatisticsEnabled()); - factory.setValueConstraint(attributes.getValueConstraint()); + clientRegionFactory.setCloningEnabled(attributes.getCloningEnabled()); + clientRegionFactory.setConcurrencyChecksEnabled(attributes.getConcurrencyChecksEnabled()); + clientRegionFactory.setConcurrencyLevel(attributes.getConcurrencyLevel()); + clientRegionFactory.setCustomEntryIdleTimeout(attributes.getCustomEntryIdleTimeout()); + clientRegionFactory.setCustomEntryTimeToLive(attributes.getCustomEntryTimeToLive()); + clientRegionFactory.setDiskStoreName(attributes.getDiskStoreName()); + clientRegionFactory.setDiskSynchronous(attributes.isDiskSynchronous()); + clientRegionFactory.setEntryIdleTimeout(attributes.getEntryIdleTimeout()); + clientRegionFactory.setEntryTimeToLive(attributes.getEntryTimeToLive()); + clientRegionFactory.setEvictionAttributes(attributes.getEvictionAttributes()); + clientRegionFactory.setInitialCapacity(attributes.getInitialCapacity()); + clientRegionFactory.setKeyConstraint(attributes.getKeyConstraint()); + clientRegionFactory.setLoadFactor(attributes.getLoadFactor()); + clientRegionFactory.setPoolName(attributes.getPoolName()); + clientRegionFactory.setRegionIdleTimeout(attributes.getRegionIdleTimeout()); + clientRegionFactory.setRegionTimeToLive(attributes.getRegionTimeToLive()); + clientRegionFactory.setStatisticsEnabled(attributes.getStatisticsEnabled()); + clientRegionFactory.setValueConstraint(attributes.getValueConstraint()); } - addCacheListeners(factory); + addCacheListeners(clientRegionFactory); if (StringUtils.hasText(poolName)) { // try to eagerly initialize the pool name, if defined as a bean if (beanFactory.isTypeMatch(poolName, Pool.class)) { if (log.isDebugEnabled()) { - log.debug(String.format("Found bean definition for pool '%1$s'. Eagerly initializing...", poolName)); + log.debug(String.format("Found bean definition for pool '%1$s'; Eagerly initializing...", poolName)); } beanFactory.getBean(poolName, Pool.class); } - factory.setPoolName(poolName); + clientRegionFactory.setPoolName(poolName); } - else { - Pool pool = beanFactory.getBean(Pool.class); - factory.setPoolName(pool.getName()); + else if (!isLocal(resolveClientRegionShortcut())) { + clientRegionFactory.setPoolName(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME); } if (diskStoreName != null) { - factory.setDiskStoreName(diskStoreName); + clientRegionFactory.setDiskStoreName(diskStoreName); } - Region clientRegion = (getParent() != null ? factory.createSubregion(getParent(), regionName) - : factory.create(regionName)); + Region clientRegion = (getParent() != null ? clientRegionFactory.createSubregion(getParent(), regionName) + : clientRegionFactory.create(regionName)); if (log.isInfoEnabled()) { if (getParent() != null) { @@ -165,6 +164,10 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean return clientRegion; } + private boolean isLocal(final ClientRegionShortcut clientRegionShortcut) { + return (clientRegionShortcut != null && clientRegionShortcut.name().startsWith("LOCAL")); + } + protected ClientRegionShortcut resolveClientRegionShortcut() { ClientRegionShortcut resolvedShortcut = this.shortcut; diff --git a/src/main/java/org/springframework/data/gemfire/client/PoolFactoryBean.java b/src/main/java/org/springframework/data/gemfire/client/PoolFactoryBean.java index fa3e9e8a..087c0db6 100644 --- a/src/main/java/org/springframework/data/gemfire/client/PoolFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/PoolFactoryBean.java @@ -18,6 +18,7 @@ package org.springframework.data.gemfire.client; import java.net.InetSocketAddress; import java.util.Collection; +import java.util.Collections; import java.util.Properties; import org.apache.commons.logging.Log; @@ -39,58 +40,64 @@ import com.gemstone.gemfire.distributed.DistributedSystem; import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem; /** - * Factory bean for easy declaration and configuration of a GemFire pool. If a - * new pool is created, its life-cycle is bound to that of the declaring - * container. - * - * Note that if the pool already exists, it will be returned as is, without any - * modifications and its life cycle untouched by this factory. - * - * @see PoolManager - * @see PoolFactory - * @see Pool - * + * FactoryBean for easy declaration and configuration of a GemFire Pool. If a new Pool is created, + * its lifecycle is bound to that of the declaring container. + * + * Note, if the Pool already exists, the existing Pool will be returned as is without any modifications + * and its lifecycle will be unaffected by this factory. + * * @author Costin Leau + * @author John Blum + * @see com.gemstone.gemfire.cache.client.Pool + * @see com.gemstone.gemfire.cache.client.PoolFactory + * @see com.gemstone.gemfire.cache.client.PoolManager */ @SuppressWarnings("unused") -public class PoolFactoryBean implements FactoryBean, InitializingBean, - DisposableBean, BeanNameAware, BeanFactoryAware { +public class PoolFactoryBean implements FactoryBean, InitializingBean, DisposableBean, BeanNameAware, + BeanFactoryAware { private static final Log log = LogFactory.getLog(PoolFactoryBean.class); - // whether the pool has been created internally or not - private boolean internalPool = true; - - private Pool pool; - - // pool settings - private String beanName; - private String name; - private Collection locators; - private Collection servers; + // indicates whether the Pool has been created internally (by this FactoryBean) or not + private volatile boolean internalPool = true; private BeanFactory beanFactory; + private Collection locators; + private Collection servers; + + private Pool pool; + + private String beanName; + private String name; + + // GemFire Pool Configuration Settings private boolean keepAlive = false; + private boolean multiUserAuthentication = PoolFactory.DEFAULT_MULTIUSER_AUTHENTICATION; + private boolean prSingleHopEnabled = PoolFactory.DEFAULT_PR_SINGLE_HOP_ENABLED; + private boolean subscriptionEnabled = PoolFactory.DEFAULT_SUBSCRIPTION_ENABLED; + private boolean threadLocalConnections = PoolFactory.DEFAULT_THREAD_LOCAL_CONNECTIONS; private int freeConnectionTimeout = PoolFactory.DEFAULT_FREE_CONNECTION_TIMEOUT; - private long idleTimeout = PoolFactory.DEFAULT_IDLE_TIMEOUT; private int loadConditioningInterval = PoolFactory.DEFAULT_LOAD_CONDITIONING_INTERVAL; private int maxConnections = PoolFactory.DEFAULT_MAX_CONNECTIONS; private int minConnections = PoolFactory.DEFAULT_MIN_CONNECTIONS; - private boolean multiUserAuthentication = PoolFactory.DEFAULT_MULTIUSER_AUTHENTICATION; - private long pingInterval = PoolFactory.DEFAULT_PING_INTERVAL; - private boolean prSingleHopEnabled = PoolFactory.DEFAULT_PR_SINGLE_HOP_ENABLED; private int readTimeout = PoolFactory.DEFAULT_READ_TIMEOUT; private int retryAttempts = PoolFactory.DEFAULT_RETRY_ATTEMPTS; - private String serverGroup = PoolFactory.DEFAULT_SERVER_GROUP; private int socketBufferSize = PoolFactory.DEFAULT_SOCKET_BUFFER_SIZE; private int statisticInterval = PoolFactory.DEFAULT_STATISTIC_INTERVAL; private int subscriptionAckInterval = PoolFactory.DEFAULT_SUBSCRIPTION_ACK_INTERVAL; - private boolean subscriptionEnabled = PoolFactory.DEFAULT_SUBSCRIPTION_ENABLED; private int subscriptionMessageTrackingTimeout = PoolFactory.DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT; private int subscriptionRedundancy = PoolFactory.DEFAULT_SUBSCRIPTION_REDUNDANCY; - private boolean threadLocalConnections = PoolFactory.DEFAULT_THREAD_LOCAL_CONNECTIONS; + + private long idleTimeout = PoolFactory.DEFAULT_IDLE_TIMEOUT; + private long pingInterval = PoolFactory.DEFAULT_PING_INTERVAL; + + private String serverGroup = PoolFactory.DEFAULT_SERVER_GROUP; + + public Pool getObject() throws Exception { + return pool; + } public Class getObjectType() { return (pool != null ? pool.getClass() : Pool.class); @@ -100,67 +107,36 @@ public class PoolFactoryBean implements FactoryBean, InitializingBean, return true; } - public Pool getObject() throws Exception { - return pool; - } - public void afterPropertiesSet() throws Exception { if (!StringUtils.hasText(name)) { - Assert.hasText(beanName, "the pool name is required"); + Assert.hasText(beanName, "The Pool name is required!"); name = beanName; } - // eagerly initialize cache (if needed) - if (InternalDistributedSystem.getAnyInstance() == null) { - Properties properties = null; - try { - ClientCacheFactoryBean clientCacheFactoryBean = beanFactory.getBean(ClientCacheFactoryBean.class); - properties = clientCacheFactoryBean.getProperties(); - } - catch (Exception ignore) { - } - - connectToTemporaryDs(properties); - - } - // first check the configured pools Pool existingPool = PoolManager.find(name); - if (existingPool != null) { - pool = existingPool; - internalPool = false; - if (log.isDebugEnabled()) - log.debug("Pool '" + name - + " already exists; using found instance..."); - } else { - if (log.isDebugEnabled()) - log.debug("No pool named '" + name - + "' found. Creating a new once..."); - if (CollectionUtils.isEmpty(locators) - && CollectionUtils.isEmpty(servers)) { - throw new IllegalArgumentException( - "at least one locator or server is required"); + if (existingPool != null) { + if (log.isDebugEnabled()) { + log.debug(String.format("A Pool with name '%1$s' already exists; using existing Pool.", name)); + } + + internalPool = false; + pool = existingPool; + } + else { + if (log.isDebugEnabled()) { + log.debug(String.format("No Pool with name '%1$s' was found. Creating a new Pool...", name)); + } + + if (CollectionUtils.isEmpty(locators) && CollectionUtils.isEmpty(servers)) { + throw new IllegalArgumentException("At least one locator or server is required!"); } internalPool = true; PoolFactory poolFactory = PoolManager.createFactory(); - if (!CollectionUtils.isEmpty(locators)) { - for (InetSocketAddress connection : locators) { - poolFactory.addLocator(connection.getHostName(), - connection.getPort()); - } - } - - if (!CollectionUtils.isEmpty(servers)) { - for (InetSocketAddress connection : servers) { - poolFactory.addServer(connection.getHostName(), - connection.getPort()); - } - } - poolFactory.setFreeConnectionTimeout(freeConnectionTimeout); poolFactory.setIdleTimeout(idleTimeout); poolFactory.setLoadConditioningInterval(loadConditioningInterval); @@ -174,13 +150,25 @@ public class PoolFactoryBean implements FactoryBean, InitializingBean, poolFactory.setServerGroup(serverGroup); poolFactory.setSocketBufferSize(socketBufferSize); poolFactory.setStatisticInterval(statisticInterval); - poolFactory.setSubscriptionEnabled(subscriptionEnabled); poolFactory.setSubscriptionAckInterval(subscriptionAckInterval); - poolFactory - .setSubscriptionMessageTrackingTimeout(subscriptionMessageTrackingTimeout); + poolFactory.setSubscriptionEnabled(subscriptionEnabled); + poolFactory.setSubscriptionMessageTrackingTimeout(subscriptionMessageTrackingTimeout); poolFactory.setSubscriptionRedundancy(subscriptionRedundancy); poolFactory.setThreadLocalConnections(threadLocalConnections); - + + for (InetSocketAddress connection : nullSafeCollection(locators)) { + poolFactory.addLocator(connection.getHostName(), connection.getPort()); + } + + for (InetSocketAddress connection : nullSafeCollection(servers)) { + poolFactory.addServer(connection.getHostName(), connection.getPort()); + } + + // eagerly initialize ClientCache (if needed) + if (InternalDistributedSystem.getAnyInstance() == null) { + doDistributedSystemConnect(resolveGemfireProperties()); + } + pool = poolFactory.create(name); } } @@ -190,217 +178,145 @@ public class PoolFactoryBean implements FactoryBean, InitializingBean, if (!pool.isDestroyed()) { pool.releaseThreadLocalConnection(); pool.destroy(keepAlive); + if (log.isDebugEnabled()) { - log.debug("Destroyed pool '" + name + "'..."); + log.debug(String.format("Destroyed Pool '%1$s'.", name)); } } } } - public void setBeanName(String name) { - this.beanName = name; + /** + * A workaround to create a Pool if no ClientCache has been created yet. Initialize a client-like + * Distributed System before initializing the Pool. + * + * @param properties GemFire System Properties. + * @see java.util.Properties + * @see com.gemstone.gemfire.distributed.DistributedSystem#connect(java.util.Properties) + */ + @SuppressWarnings("deprecation") + static void doDistributedSystemConnect(Properties properties) { + Properties gemfireProperties = (properties != null ? (Properties) properties.clone() : new Properties()); + gemfireProperties.setProperty("locators", ""); + gemfireProperties.setProperty("mcast-port", "0"); + DistributedSystem.connect(gemfireProperties); } - /** - * @param pool - * the pool to set - */ - public void setPool(Pool pool) { - this.pool = pool; + /* (non-Javadoc) */ + private Collection nullSafeCollection(final Collection list) { + return (list != null ? list : Collections.emptyList()); } - /** - * @param name - * the name to set - */ - public void setName(String name) { - this.name = name; - } - - /** - * @param locators - * the locators to set - */ - public void setLocators(Collection locators) { - this.locators = locators; - } - - /** - * @param servers - * the servers to set - */ - public void setServers(Collection servers) { - this.servers = servers; - } - - /** - * @param keepAlive - * the keepAlive to set - */ - public void setKeepAlive(boolean keepAlive) { - this.keepAlive = keepAlive; - } - - /** - * @param freeConnectionTimeout - * the freeConnectionTimeout to set - */ - public void setFreeConnectionTimeout(int freeConnectionTimeout) { - this.freeConnectionTimeout = freeConnectionTimeout; - } - - /** - * @param idleTimeout - * the idleTimeout to set - */ - public void setIdleTimeout(long idleTimeout) { - this.idleTimeout = idleTimeout; - } - - /** - * @param loadConditioningInterval - * the loadConditioningInterval to set - */ - public void setLoadConditioningInterval(int loadConditioningInterval) { - this.loadConditioningInterval = loadConditioningInterval; - } - - /** - * @param maxConnections - * the maxConnections to set - */ - public void setMaxConnections(int maxConnections) { - this.maxConnections = maxConnections; - } - - /** - * @param minConnections - * the minConnections to set - */ - public void setMinConnections(int minConnections) { - this.minConnections = minConnections; - } - - /** - * @param pingInterval - * the pingInterval to set - */ - public void setPingInterval(long pingInterval) { - this.pingInterval = pingInterval; - } - - /** - * @param readTimeout - * the readTimeout to set - */ - public void setReadTimeout(int readTimeout) { - this.readTimeout = readTimeout; - } - - /** - * @param retryAttempts - * the retryAttempts to set - */ - public void setRetryAttempts(int retryAttempts) { - this.retryAttempts = retryAttempts; - } - - /** - * @param serverGroup - * the serverGroup to set - */ - public void setServerGroup(String serverGroup) { - this.serverGroup = serverGroup; - } - - /** - * @param socketBufferSize - * the socketBufferSize to set - */ - public void setSocketBufferSize(int socketBufferSize) { - this.socketBufferSize = socketBufferSize; - } - - /** - * @param statisticInterval - * the statisticInterval to set - */ - public void setStatisticInterval(int statisticInterval) { - this.statisticInterval = statisticInterval; - } - - /** - * @param subscriptionAckInterval - * the subscriptionAckInterval to set - */ - public void setSubscriptionAckInterval(int subscriptionAckInterval) { - this.subscriptionAckInterval = subscriptionAckInterval; - } - - /** - * @param subscriptionEnabled - * the subscriptionEnabled to set - */ - public void setSubscriptionEnabled(boolean subscriptionEnabled) { - this.subscriptionEnabled = subscriptionEnabled; - } - - /** - * @param subscriptionMessageTrackingTimeout - * the subscriptionMessageTrackingTimeout to set - */ - public void setSubscriptionMessageTrackingTimeout( - int subscriptionMessageTrackingTimeout) { - this.subscriptionMessageTrackingTimeout = subscriptionMessageTrackingTimeout; - } - - /** - * @param subscriptionRedundancy - * the subscriptionRedundancy to set - */ - public void setSubscriptionRedundancy(int subscriptionRedundancy) { - this.subscriptionRedundancy = subscriptionRedundancy; - } - - /** - * @param threadLocalConnections - * the threadLocalConnections to set - */ - public void setThreadLocalConnections(boolean threadLocalConnections) { - this.threadLocalConnections = threadLocalConnections; + /* (non-Javadoc) */ + private Properties resolveGemfireProperties() { + try { + ClientCacheFactoryBean clientCacheFactoryBean = beanFactory.getBean(ClientCacheFactoryBean.class); + return clientCacheFactoryBean.getProperties(); + } + catch (Exception ignore) { + return null; + } } public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } - /** - * @param multiUserAuthentication - * the multiUserAuthentication to set - */ + public void setBeanName(String name) { + this.beanName = name; + } + + public void setName(String name) { + this.name = name; + } + + public void setPool(Pool pool) { + this.pool = pool; + } + + public void setFreeConnectionTimeout(int freeConnectionTimeout) { + this.freeConnectionTimeout = freeConnectionTimeout; + } + + public void setIdleTimeout(long idleTimeout) { + this.idleTimeout = idleTimeout; + } + + public void setKeepAlive(boolean keepAlive) { + this.keepAlive = keepAlive; + } + + public void setLoadConditioningInterval(int loadConditioningInterval) { + this.loadConditioningInterval = loadConditioningInterval; + } + + public void setLocators(Collection locators) { + this.locators = locators; + } + + public void setMaxConnections(int maxConnections) { + this.maxConnections = maxConnections; + } + + public void setMinConnections(int minConnections) { + this.minConnections = minConnections; + } + public void setMultiUserAuthentication(boolean multiUserAuthentication) { this.multiUserAuthentication = multiUserAuthentication; } - /** - * @param prSingleHopEnabled - * the prSingleHopEnabled to set - */ + public void setPingInterval(long pingInterval) { + this.pingInterval = pingInterval; + } + + public void setReadTimeout(int readTimeout) { + this.readTimeout = readTimeout; + } + + public void setRetryAttempts(int retryAttempts) { + this.retryAttempts = retryAttempts; + } + + public void setServerGroup(String serverGroup) { + this.serverGroup = serverGroup; + } + + public void setServers(Collection servers) { + this.servers = servers; + } + + public void setSocketBufferSize(int socketBufferSize) { + this.socketBufferSize = socketBufferSize; + } + + public void setStatisticInterval(int statisticInterval) { + this.statisticInterval = statisticInterval; + } + public void setPrSingleHopEnabled(boolean prSingleHopEnabled) { this.prSingleHopEnabled = prSingleHopEnabled; } - - /* - * A work around to create a pool if no cache has been created yet - * initialize a client-like Distributed System before initializing - * the pool - */ - @SuppressWarnings("deprecation") - static void connectToTemporaryDs(Properties properties) { - Properties props = properties != null? (Properties) properties.clone() : new Properties(); - props.setProperty("mcast-port", "0"); - props.setProperty("locators", ""); - DistributedSystem.connect(props); + + public void setSubscriptionAckInterval(int subscriptionAckInterval) { + this.subscriptionAckInterval = subscriptionAckInterval; + } + + public void setSubscriptionEnabled(boolean subscriptionEnabled) { + this.subscriptionEnabled = subscriptionEnabled; + } + + public void setSubscriptionMessageTrackingTimeout( + int subscriptionMessageTrackingTimeout) { + this.subscriptionMessageTrackingTimeout = subscriptionMessageTrackingTimeout; + } + + public void setSubscriptionRedundancy(int subscriptionRedundancy) { + this.subscriptionRedundancy = subscriptionRedundancy; + } + + public void setThreadLocalConnections(boolean threadLocalConnections) { + this.threadLocalConnections = threadLocalConnections; } } diff --git a/src/main/java/org/springframework/data/gemfire/config/GemfireConstants.java b/src/main/java/org/springframework/data/gemfire/config/GemfireConstants.java index 65e73cf7..688fb523 100644 --- a/src/main/java/org/springframework/data/gemfire/config/GemfireConstants.java +++ b/src/main/java/org/springframework/data/gemfire/config/GemfireConstants.java @@ -12,15 +12,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.data.gemfire.config; + /** * * @author David Turanski - * + * @author John Blum */ public interface GemfireConstants { - static final String DEFAULT_GEMFIRE_POOL_NAME = "gemfirePool"; static final String DEFAULT_GEMFIRE_CACHE_NAME = "gemfireCache"; - static final String DEFAULT_GEMFIRE_TXMANAGER_NAME = "gemfireTransactionManager"; static final String DEFAULT_GEMFIRE_FUNCTION_SERVICE_NAME = "gemfireFunctionService"; + static final String DEFAULT_GEMFIRE_POOL_NAME = "DEFAULT"; + static final String DEFAULT_GEMFIRE_TXMANAGER_NAME = "gemfireTransactionManager"; } diff --git a/src/main/java/org/springframework/data/gemfire/config/PoolParser.java b/src/main/java/org/springframework/data/gemfire/config/PoolParser.java index 4e73ba19..f93eb18a 100644 --- a/src/main/java/org/springframework/data/gemfire/config/PoolParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/PoolParser.java @@ -71,30 +71,38 @@ class PoolParser extends AbstractSimpleBeanDefinitionParser { } } - private Object parseServer(Element subElement) { - return parseConnection(subElement); + private BeanDefinition parseConnection(Element element) { + BeanDefinitionBuilder inetSocketAddressBuilder = BeanDefinitionBuilder.genericBeanDefinition( + InetSocketAddress.class); + + inetSocketAddressBuilder.addConstructorArgValue(element.getAttribute("host")); + inetSocketAddressBuilder.addConstructorArgValue(element.getAttribute("port")); + + return inetSocketAddressBuilder.getBeanDefinition(); } private Object parseLocator(Element subElement) { return parseConnection(subElement); } - private BeanDefinition parseConnection(Element element) { - BeanDefinitionBuilder defBuilder = BeanDefinitionBuilder.genericBeanDefinition(InetSocketAddress.class); - defBuilder.addConstructorArgValue(element.getAttribute("host")); - defBuilder.addConstructorArgValue(element.getAttribute("port")); - return defBuilder.getBeanDefinition(); + private Object parseServer(Element subElement) { + return parseConnection(subElement); } + /* (non-Javadoc) */ @Override protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) - throws BeanDefinitionStoreException { - String name = super.resolveId(element, definition, parserContext); - if (!StringUtils.hasText(name)) { - name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME; - //For backward compatibility + throws BeanDefinitionStoreException { + + String id = super.resolveId(element, definition, parserContext); + + if (!StringUtils.hasText(id)) { + id = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME; + parserContext.getRegistry().registerAlias(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, "gemfirePool"); parserContext.getRegistry().registerAlias(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, "gemfire-pool"); } - return name; + + return id; } -} \ No newline at end of file + +} diff --git a/src/test/java/org/springframework/data/gemfire/client/ClientCacheTest.java b/src/test/java/org/springframework/data/gemfire/client/ClientCacheTest.java index bfb45a47..3ceec00c 100644 --- a/src/test/java/org/springframework/data/gemfire/client/ClientCacheTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/ClientCacheTest.java @@ -24,6 +24,7 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.data.gemfire.config.GemfireConstants; import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -48,7 +49,7 @@ public class ClientCacheTest { @Test public void test() { - assertEquals("gemfirePool", region.getAttributes().getPoolName()); + assertEquals(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, region.getAttributes().getPoolName()); } @Test diff --git a/src/test/java/org/springframework/data/gemfire/client/ClientRegionFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/client/ClientRegionFactoryBeanTest.java index 512036b1..bcfb2c11 100644 --- a/src/test/java/org/springframework/data/gemfire/client/ClientRegionFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/ClientRegionFactoryBeanTest.java @@ -21,17 +21,28 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.io.InputStream; + import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.BeanFactory; +import org.springframework.core.io.Resource; import org.springframework.data.gemfire.TestUtils; import com.gemstone.gemfire.cache.DataPolicy; +import com.gemstone.gemfire.cache.EvictionAttributes; +import com.gemstone.gemfire.cache.ExpirationAttributes; import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.RegionAttributes; import com.gemstone.gemfire.cache.client.ClientCache; import com.gemstone.gemfire.cache.client.ClientRegionFactory; import com.gemstone.gemfire.cache.client.ClientRegionShortcut; @@ -56,28 +67,183 @@ public class ClientRegionFactoryBeanTest { factoryBean = null; } - @SuppressWarnings("unchecked") @Test - public void testLookupFallbackFailingToUseProvidedShortcut() throws Exception { + @SuppressWarnings({ "deprecation", "unchecked" }) + public void testLookupFallbackUsingDefaultShortcut() throws Exception { + final String testRegionName = "TestRegion"; + + ClientCache mockClientCache = mock(ClientCache.class); + ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); + Region mockRegion = mock(Region.class); + + when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.LOCAL))).thenReturn(mockClientRegionFactory); + when(mockClientRegionFactory.create(eq(testRegionName))).thenReturn(mockRegion); + + RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); + + when(mockRegionAttributes.getCloningEnabled()).thenReturn(false); + when(mockRegionAttributes.getConcurrencyChecksEnabled()).thenReturn(true); + when(mockRegionAttributes.getConcurrencyLevel()).thenReturn(8); + when(mockRegionAttributes.getCustomEntryIdleTimeout()).thenReturn(null); + when(mockRegionAttributes.getCustomEntryTimeToLive()).thenReturn(null); + when(mockRegionAttributes.getDiskStoreName()).thenReturn("TestDiskStoreOne"); + when(mockRegionAttributes.isDiskSynchronous()).thenReturn(false); + when(mockRegionAttributes.getEntryIdleTimeout()).thenReturn(mock(ExpirationAttributes.class)); + when(mockRegionAttributes.getEntryTimeToLive()).thenReturn(mock(ExpirationAttributes.class)); + when(mockRegionAttributes.getEvictionAttributes()).thenReturn(mock(EvictionAttributes.class)); + when(mockRegionAttributes.getInitialCapacity()).thenReturn(101); + when(mockRegionAttributes.getKeyConstraint()).thenReturn(Long.class); + when(mockRegionAttributes.getLoadFactor()).thenReturn(0.75f); + when(mockRegionAttributes.getPoolName()).thenReturn("TestPoolOne"); + when(mockRegionAttributes.getRegionIdleTimeout()).thenReturn(mock(ExpirationAttributes.class)); + when(mockRegionAttributes.getRegionTimeToLive()).thenReturn(mock(ExpirationAttributes.class)); + when(mockRegionAttributes.getStatisticsEnabled()).thenReturn(true); + when(mockRegionAttributes.getValueConstraint()).thenReturn(Number.class); + + BeanFactory mockBeanFactory = mock(BeanFactory.class); + Pool mockPool = mock(Pool.class); + Resource mockSnapshot = mock(Resource.class, "Snapshot"); + + when(mockBeanFactory.isTypeMatch(eq("TestPoolTwo"), eq(Pool.class))).thenReturn(true); + when(mockBeanFactory.getBean(eq("TestPoolTwo"))).thenReturn(mockPool); + when(mockPool.getName()).thenReturn("TestPoolTwo"); + when(mockSnapshot.getInputStream()).thenReturn(mock(InputStream.class)); + + factoryBean.setAttributes(mockRegionAttributes); + factoryBean.setBeanFactory(mockBeanFactory); + factoryBean.setDiskStoreName("TestDiskStoreTwo"); + factoryBean.setPersistent(false); + factoryBean.setPoolName("TestPoolTwo"); + factoryBean.setSnapshot(mockSnapshot); + factoryBean.setShortcut(null); + + Region actualRegion = factoryBean.lookupFallback(mockClientCache, testRegionName); + + assertSame(mockRegion, actualRegion); + + verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.LOCAL)); + verify(mockClientRegionFactory, times(1)).setCloningEnabled(eq(false)); + verify(mockClientRegionFactory, times(1)).setConcurrencyChecksEnabled(eq(true)); + verify(mockClientRegionFactory, times(1)).setConcurrencyLevel(eq(8)); + verify(mockClientRegionFactory, times(1)).setCustomEntryIdleTimeout(null); + verify(mockClientRegionFactory, times(1)).setCustomEntryTimeToLive(null); + verify(mockClientRegionFactory, times(1)).setDiskStoreName(eq("TestDiskStoreOne")); + verify(mockClientRegionFactory, times(1)).setDiskSynchronous(eq(false)); + verify(mockClientRegionFactory, times(1)).setEntryIdleTimeout(any(ExpirationAttributes.class)); + verify(mockClientRegionFactory, times(1)).setEntryTimeToLive(any(ExpirationAttributes.class)); + verify(mockClientRegionFactory, times(1)).setEvictionAttributes(any(EvictionAttributes.class)); + verify(mockClientRegionFactory, times(1)).setInitialCapacity(eq(101)); + verify(mockClientRegionFactory, times(1)).setKeyConstraint(eq(Long.class)); + verify(mockClientRegionFactory, times(1)).setLoadFactor(eq(0.75f)); + verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPoolOne")); + verify(mockClientRegionFactory, times(1)).setRegionIdleTimeout(any(ExpirationAttributes.class)); + verify(mockClientRegionFactory, times(1)).setRegionTimeToLive(any(ExpirationAttributes.class)); + verify(mockClientRegionFactory, times(1)).setStatisticsEnabled(eq(true)); + verify(mockClientRegionFactory, times(1)).setValueConstraint(eq(Number.class)); + verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPoolTwo")); + verify(mockClientRegionFactory, times(1)).setDiskStoreName(eq("TestDiskStoreTwo")); + verify(mockClientRegionFactory, times(1)).create(eq(testRegionName)); + verify(mockRegion, times(1)).loadSnapshot(any(InputStream.class)); + } + + @Test + @SuppressWarnings({ "deprecation", "unchecked" }) + public void testLookupFallbackUsingDefaultPersistentShortcut() throws Exception { + ClientCache mockClientCache = mock(ClientCache.class); + ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); + Region mockRegion = mock(Region.class); + + when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.LOCAL_PERSISTENT))).thenReturn(mockClientRegionFactory); + when(mockClientRegionFactory.create(eq("TestRegion"))).thenReturn(mockRegion); + + BeanFactory mockBeanFactory = mock(BeanFactory.class); + + when(mockBeanFactory.isTypeMatch(eq("TestPool"), eq(Pool.class))).thenReturn(false); + + factoryBean.setAttributes(null); + factoryBean.setBeanFactory(mockBeanFactory); + factoryBean.setPersistent(true); + factoryBean.setPoolName("TestPool"); + factoryBean.setShortcut(null); + + Region actualRegion = factoryBean.lookupFallback(mockClientCache, "TestRegion"); + + assertSame(mockRegion, actualRegion); + + verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.LOCAL_PERSISTENT)); + verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPool")); + verify(mockClientRegionFactory, times(1)).create(eq("TestRegion")); + verify(mockBeanFactory, never()).getBean(eq("TestPool")); + verify(mockRegion, never()).loadSnapshot(any(InputStream.class)); + } + + @Test + @SuppressWarnings("unchecked") + public void testLookupFallbackWithSpecifiedShortcut() throws Exception { + ClientCache mockClientCache = mock(ClientCache.class); + ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); + Region mockRegion = mock(Region.class); + + when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.CACHING_PROXY))).thenReturn(mockClientRegionFactory); + when(mockClientRegionFactory.create(eq("TestRegion"))).thenReturn(mockRegion); + + factoryBean.setAttributes(null); + factoryBean.setBeanFactory(null); factoryBean.setShortcut(ClientRegionShortcut.CACHING_PROXY); - BeanFactory beanFactory = mock(BeanFactory.class); - Pool pool = mock(Pool.class); + Region actualRegion = factoryBean.lookupFallback(mockClientCache, "TestRegion"); - when(beanFactory.getBean(Pool.class)).thenReturn(pool); + assertSame(mockRegion, actualRegion); - factoryBean.setBeanFactory(beanFactory); + verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.CACHING_PROXY)); + verify(mockClientRegionFactory, times(1)).create(eq("TestRegion")); + } - ClientCache cache = mock(ClientCache.class); - ClientRegionFactory clientRegionFactory = mock(ClientRegionFactory.class); - Region expectedRegion = mock(Region.class); + @Test + @SuppressWarnings("unchecked") + public void testLookupFallbackWithSubRegionCreation() throws Exception { + ClientCache mockClientCache = mock(ClientCache.class); + ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); + Region mockParentRegion = mock(Region.class, "Parent"); + Region mockSubRegion = mock(Region.class, "SubRegion"); - when(cache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY)).thenReturn(clientRegionFactory); - when(clientRegionFactory.create("testRegion")).thenReturn(expectedRegion); + when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.PROXY))).thenReturn(mockClientRegionFactory); + when(mockClientRegionFactory.createSubregion(eq(mockParentRegion), eq("TestSubRegion"))).thenReturn(mockSubRegion); - Region actualRegion = factoryBean.lookupFallback(cache, "testRegion"); + factoryBean.setAttributes(null); + factoryBean.setBeanFactory(null); + factoryBean.setParent(mockParentRegion); + factoryBean.setShortcut(ClientRegionShortcut.PROXY); - assertSame(expectedRegion, actualRegion); + Region actualRegion = factoryBean.lookupFallback(mockClientCache, "TestSubRegion"); + + assertSame(mockSubRegion, actualRegion); + + verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.PROXY)); + verify(mockClientRegionFactory, times(1)).createSubregion(eq(mockParentRegion), eq("TestSubRegion")); + } + + @Test + @SuppressWarnings("unchecked") + public void testLookupFallbackWithUnspecifiedPool() throws Exception { + ClientCache mockClientCache = mock(ClientCache.class); + ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); + Region mockRegion = mock(Region.class); + + when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.LOCAL_HEAP_LRU))).thenReturn(mockClientRegionFactory); + when(mockClientRegionFactory.create(eq("TestRegion"))).thenReturn(mockRegion); + + factoryBean.setAttributes(null); + factoryBean.setBeanFactory(null); + factoryBean.setShortcut(ClientRegionShortcut.LOCAL_HEAP_LRU); + + Region actualRegion = factoryBean.lookupFallback(mockClientCache, "TestRegion"); + + assertSame(mockRegion, actualRegion); + + verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.LOCAL_HEAP_LRU)); + verify(mockClientRegionFactory, times(1)).create(eq("TestRegion")); + verify(mockClientRegionFactory, never()).setPoolName(any(String.class)); } @Test diff --git a/src/test/java/org/springframework/data/gemfire/config/CacheNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/CacheNamespaceTest.java index 2283054d..cfb4d5cd 100644 --- a/src/test/java/org/springframework/data/gemfire/config/CacheNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/CacheNamespaceTest.java @@ -47,37 +47,39 @@ import com.gemstone.gemfire.cache.util.TimestampedEntryEvent; * @author Costin Leau */ @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="/org/springframework/data/gemfire/config/cache-ns.xml", - initializers=GemfireTestApplicationContextInitializer.class) +@ContextConfiguration(locations="cache-ns.xml", initializers=GemfireTestApplicationContextInitializer.class) +@SuppressWarnings("unused") public class CacheNamespaceTest{ - @Autowired ApplicationContext ctx; - + + @Autowired + private ApplicationContext applicationContext; + @Test public void testBasicCache() throws Exception { - assertTrue(ctx.containsBean("gemfireCache")); + assertTrue(applicationContext.containsBean("gemfireCache")); //Check alias is registered - assertTrue(ctx.containsBean("gemfire-cache")); + assertTrue(applicationContext.containsBean("gemfire-cache")); // - CacheFactoryBean cfb = (CacheFactoryBean) ctx.getBean("&gemfireCache"); + CacheFactoryBean cfb = (CacheFactoryBean) applicationContext.getBean("&gemfireCache"); assertNull(TestUtils.readField("cacheXml", cfb)); assertNull(TestUtils.readField("properties", cfb)); } @Test public void testNamedCache() throws Exception { - assertTrue(ctx.containsBean("cache-with-name")); - CacheFactoryBean cfb = (CacheFactoryBean) ctx.getBean("&cache-with-name"); + assertTrue(applicationContext.containsBean("cache-with-name")); + CacheFactoryBean cfb = (CacheFactoryBean) applicationContext.getBean("&cache-with-name"); assertNull(TestUtils.readField("cacheXml", cfb)); assertNull(TestUtils.readField("properties", cfb)); } @Test public void testCacheWithXml() throws Exception { - assertTrue(ctx.containsBean("cache-with-xml")); - CacheFactoryBean cfb = (CacheFactoryBean) ctx.getBean("&cache-with-xml"); + assertTrue(applicationContext.containsBean("cache-with-xml")); + CacheFactoryBean cfb = (CacheFactoryBean) applicationContext.getBean("&cache-with-xml"); Resource res = TestUtils.readField("cacheXml", cfb); assertEquals("gemfire-cache.xml", res.getFilename()); - assertEquals(ctx.getBean("props"), TestUtils.readField("properties", cfb)); + assertEquals(applicationContext.getBean("props"), TestUtils.readField("properties", cfb)); assertEquals(Boolean.FALSE, TestUtils.readField("pdxIgnoreUnreadFields", cfb)); assertEquals(Boolean.TRUE, TestUtils.readField("pdxPersistent", cfb)); @@ -86,17 +88,17 @@ public class CacheNamespaceTest{ @Test public void testCacheWithGatewayConflictResolver() { - Cache cache = ctx.getBean("cache-with-conflict-resolver", Cache.class); + Cache cache = applicationContext.getBean("cache-with-conflict-resolver", Cache.class); assertNotNull(cache.getGatewayConflictResolver()); assertTrue(cache.getGatewayConflictResolver() instanceof TestConflictResolver); } @Test(expected = IllegalArgumentException.class) public void testNoBeanFactory() throws Exception { - assertTrue(ctx.containsBean("no-bl")); - CacheFactoryBean cfb = (CacheFactoryBean) ctx.getBean("&no-bl"); + assertTrue(applicationContext.containsBean("no-bl")); + CacheFactoryBean cfb = (CacheFactoryBean) applicationContext.getBean("&no-bl"); - assertThat(ReflectionTestUtils.getField(cfb, "factoryLocator"), is(nullValue())); + assertThat(ReflectionTestUtils.getField(cfb, "beanFactoryLocator"), is(nullValue())); GemfireBeanFactoryLocator locator = new GemfireBeanFactoryLocator(); try { @@ -110,24 +112,24 @@ public class CacheNamespaceTest{ @Test public void testBasicClientCache() throws Exception { - assertTrue(ctx.containsBean("client-cache")); - ClientCacheFactoryBean cfb = (ClientCacheFactoryBean) ctx.getBean("&client-cache"); + assertTrue(applicationContext.containsBean("client-cache")); + ClientCacheFactoryBean cfb = (ClientCacheFactoryBean) applicationContext.getBean("&client-cache"); assertNull(TestUtils.readField("cacheXml", cfb)); assertNull(TestUtils.readField("properties", cfb)); } @Test public void testBasicClientCacheWithXml() throws Exception { - assertTrue(ctx.containsBean("client-cache-with-xml")); - ClientCacheFactoryBean cfb = (ClientCacheFactoryBean) ctx.getBean("&client-cache-with-xml"); + assertTrue(applicationContext.containsBean("client-cache-with-xml")); + ClientCacheFactoryBean cfb = (ClientCacheFactoryBean) applicationContext.getBean("&client-cache-with-xml"); Resource res = TestUtils.readField("cacheXml", cfb); assertEquals("gemfire-client-cache.xml", res.getFilename()); } @Test public void testHeapTunedCache() throws Exception { - assertTrue(ctx.containsBean("heap-tuned-cache")); - CacheFactoryBean cfb = (CacheFactoryBean) ctx.getBean("&heap-tuned-cache"); + assertTrue(applicationContext.containsBean("heap-tuned-cache")); + CacheFactoryBean cfb = (CacheFactoryBean) applicationContext.getBean("&heap-tuned-cache"); Float chp = (Float) TestUtils.readField("criticalHeapPercentage", cfb); Float ehp = (Float) TestUtils.readField("evictionHeapPercentage", cfb); assertEquals(70, chp, 0.0001); @@ -137,8 +139,7 @@ public class CacheNamespaceTest{ public static class TestConflictResolver implements GatewayConflictResolver { @Override public void onEvent(TimestampedEntryEvent arg0, GatewayConflictHelper arg1) { - // TODO Auto-generated method stub - } } + } diff --git a/src/test/java/org/springframework/data/gemfire/config/PoolNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/PoolNamespaceTest.java index cea18ad5..b126285e 100644 --- a/src/test/java/org/springframework/data/gemfire/config/PoolNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/PoolNamespaceTest.java @@ -18,6 +18,7 @@ package org.springframework.data.gemfire.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.net.InetSocketAddress; @@ -38,54 +39,63 @@ import com.gemstone.gemfire.cache.client.PoolManager; /** * @author Costin Leau + * @author John Blum */ @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="pool-ns.xml", - initializers=GemfireTestApplicationContextInitializer.class) +@ContextConfiguration(locations="pool-ns.xml", initializers=GemfireTestApplicationContextInitializer.class) +@SuppressWarnings("unused") public class PoolNamespaceTest { - + @Autowired private ApplicationContext context; @Test - public void testAll() throws Exception { - testBasicClient(); - testComplexPool(); - } - - private void testBasicClient() throws Exception { + public void testBasicClient() throws Exception { + assertTrue(context.containsBean("DEFAULT")); assertTrue(context.containsBean("gemfirePool")); - //Check old style alias also registered assertTrue(context.containsBean("gemfire-pool")); - - assertEquals(context.getBean("gemfirePool"), PoolManager.find("gemfirePool")); - PoolFactoryBean pfb = (PoolFactoryBean) context.getBean("&gemfirePool"); - Collection locators = TestUtils.readField("locators", pfb); + assertEquals(context.getBean("gemfirePool"), PoolManager.find("DEFAULT")); + + PoolFactoryBean poolFactoryBean = (PoolFactoryBean) context.getBean("&gemfirePool"); + Collection locators = TestUtils.readField("locators", poolFactoryBean); + + assertNotNull(locators); assertEquals(1, locators.size()); + InetSocketAddress locator = locators.iterator().next(); + assertEquals("localhost", locator.getHostName()); assertEquals(40403, locator.getPort()); } - private void testComplexPool() throws Exception { + @Test + public void testComplexPool() throws Exception { assertTrue(context.containsBean("complex")); - PoolFactoryBean pfb = (PoolFactoryBean) context.getBean("&complex"); - assertEquals(30, TestUtils.readField("retryAttempts", pfb)); - assertEquals(6000, TestUtils.readField("freeConnectionTimeout", pfb)); - assertEquals(5000l, TestUtils.readField("pingInterval", pfb)); - assertTrue((Boolean) TestUtils.readField("subscriptionEnabled", pfb)); - assertFalse((Boolean) TestUtils.readField("multiUserAuthentication", pfb)); - assertTrue((Boolean) TestUtils.readField("prSingleHopEnabled", pfb)); - Collection servers = TestUtils.readField("servers", pfb); + PoolFactoryBean poolFactoryBean = (PoolFactoryBean) context.getBean("&complex"); + + assertEquals(30, TestUtils.readField("retryAttempts", poolFactoryBean)); + assertEquals(6000, TestUtils.readField("freeConnectionTimeout", poolFactoryBean)); + assertEquals(5000l, TestUtils.readField("pingInterval", poolFactoryBean)); + assertTrue((Boolean) TestUtils.readField("subscriptionEnabled", poolFactoryBean)); + assertFalse((Boolean) TestUtils.readField("multiUserAuthentication", poolFactoryBean)); + assertTrue((Boolean) TestUtils.readField("prSingleHopEnabled", poolFactoryBean)); + + Collection servers = TestUtils.readField("servers", poolFactoryBean); + + assertNotNull(servers); assertEquals(2, servers.size()); + Iterator iterator = servers.iterator(); InetSocketAddress server = iterator.next(); + assertEquals("localhost", server.getHostName()); assertEquals(40404, server.getPort()); server = iterator.next(); + assertEquals("localhost", server.getHostName()); assertEquals(40405, server.getPort()); } + } diff --git a/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java b/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java index 11a06a24..0db100d2 100644 --- a/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java +++ b/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java @@ -30,13 +30,10 @@ public class MockCacheFactoryBean extends CacheFactoryBean { this.useBeanFactoryLocator = false; } - /** - * @param bean - */ public MockCacheFactoryBean(CacheFactoryBean cacheFactoryBean) { this(); if (cacheFactoryBean != null) { - this.factoryLocator = cacheFactoryBean.getBeanFactoryLocator(); + this.beanFactoryLocator = cacheFactoryBean.getBeanFactoryLocator(); this.beanFactory = cacheFactoryBean.getBeanFactory(); this.beanName = cacheFactoryBean.getBeanName(); this.beanClassLoader = cacheFactoryBean.getBeanClassLoader(); diff --git a/src/test/java/org/springframework/data/gemfire/test/MockClientCacheFactoryBean.java b/src/test/java/org/springframework/data/gemfire/test/MockClientCacheFactoryBean.java index edc8b522..ad06c83c 100644 --- a/src/test/java/org/springframework/data/gemfire/test/MockClientCacheFactoryBean.java +++ b/src/test/java/org/springframework/data/gemfire/test/MockClientCacheFactoryBean.java @@ -29,13 +29,10 @@ public class MockClientCacheFactoryBean extends ClientCacheFactoryBean { this.cache = new StubCache(); } - /** - * @param bean - */ public MockClientCacheFactoryBean(ClientCacheFactoryBean cacheFactoryBean) { this(); if (cacheFactoryBean != null) { - this.factoryLocator = cacheFactoryBean.getBeanFactoryLocator(); + this.beanFactoryLocator = cacheFactoryBean.getBeanFactoryLocator(); this.beanFactory = cacheFactoryBean.getBeanFactory(); this.beanName = cacheFactoryBean.getBeanName(); this.beanClassLoader = cacheFactoryBean.getBeanClassLoader(); diff --git a/src/test/resources/clientcache-with-regions.xml b/src/test/resources/clientcache-with-regions.xml index f7293d03..621fc9c8 100644 --- a/src/test/resources/clientcache-with-regions.xml +++ b/src/test/resources/clientcache-with-regions.xml @@ -2,9 +2,6 @@ - - - diff --git a/src/test/resources/org/springframework/data/gemfire/client/client-cache.xml b/src/test/resources/org/springframework/data/gemfire/client/client-cache.xml index b0a76411..a892906d 100644 --- a/src/test/resources/org/springframework/data/gemfire/client/client-cache.xml +++ b/src/test/resources/org/springframework/data/gemfire/client/client-cache.xml @@ -1,13 +1,26 @@ - - - - - - + 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/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 +"> + + + ClientCacheTests + 0 + warning + + + + + + + + + + diff --git a/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-context.xml b/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-context.xml index 416eb654..55bbacf6 100644 --- a/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-context.xml @@ -1,19 +1,18 @@ + http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd +"> - - - - - + + + +