diff --git a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java index a55d3f3f..8e5bf563 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; @@ -109,7 +110,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, protected Float criticalHeapPercentage; protected Float evictionHeapPercentage; - protected GemfireBeanFactoryLocator factoryLocator; + protected GemfireBeanFactoryLocator beanFactoryLocator; protected Integer lockLease; protected Integer lockTimeout; @@ -129,6 +130,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, protected Resource cacheXml; protected String beanName; + private String cacheResolutionMessagePrefix; protected String pdxDiskStoreName; protected TransactionWriter transactionWriter; @@ -214,7 +216,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, private final CacheFactory factory; - PdxOptions(CacheFactory factory) { + private PdxOptions(CacheFactory factory) { this.factory = factory; } @@ -239,109 +241,67 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, } } - 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) { + if (GemfireUtils.isGemfireVersion8OrAbove()) { + gemfireProperties.setProperty("disable-auto-reconnect", String.valueOf( + !Boolean.TRUE.equals(getEnableAutoReconnect()))); + gemfireProperties.setProperty("use-cluster-configuration", String.valueOf( + Boolean.TRUE.equals(getUseClusterConfiguration()))); + } + } + + /* (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(getProperties()); - - if (isPdxSettingsSpecified()) { - Assert.isTrue(ClassUtils.isPresent("com.gemstone.gemfire.pdx.PdxSerializer", beanClassLoader), - "Cannot set PDX options since GemFire 6.6 not detected."); - applyPdxOptions(factory); - } - - cache = (Cache) createCache(factory); - messagePrefix = "Created new"; - } - - 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); - } + 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] in Groups [%3$s] with Roles [%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("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(String.format("Initialized Cache from '%1$s'.", 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) { @@ -350,82 +310,222 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, } /** - * 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 (isCacheXmlAvailable() ? ((CacheFactory) factory).set( + // DistributionConfig.CACHE_XML_FILE_NAME, getCacheXmlFile().getAbsolutePath()) : 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 Object createFactory(Properties gemfireProperties) { - return new CacheFactory(gemfireProperties); + /* (non-Javadoc) */ + private void registerTransactionWriter(Cache cache) { + if (transactionWriter != null) { + cache.getCacheTransactionManager().setWriter(transactionWriter); + } } - protected GemFireCache fetchCache() { - return (cache != null ? cache : CacheFactory.getAnyInstance()); + /* (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; } } } @@ -471,9 +571,10 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, } /** - * Sets the cache configuration. + * Sets the Cache configuration. * - * @param cacheXml the cacheXml to set + * @param cacheXml the cache.xml Resource used to initialize the GemFire Cache. + * @see org.springframework.core.io.Resource */ public void setCacheXml(Resource cacheXml) { this.cacheXml = cacheXml; @@ -718,7 +819,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, * @return the beanFactoryLocator */ public GemfireBeanFactoryLocator getBeanFactoryLocator() { - return factoryLocator; + return beanFactoryLocator; } /** @@ -735,21 +836,37 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, return cacheXml; } + /* (non-Javadoc) */ + private File getCacheXmlFile() { + try { + return getCacheXml().getFile(); + } + catch (IOException e) { + throw new IllegalStateException(String.format("Resource (%1$s) is not resolvable as a file", e)); + } + } + + /* (non-Javadoc) */ + private boolean isCacheXmlAvailable() { + try { + Resource localCacheXml = getCacheXml(); + return (localCacheXml != null && localCacheXml.getFile().isFile()); + } + catch (IOException ignore) { + return false; + } + } + /** * @return the properties */ public Properties getProperties() { - if (properties == null) { - properties = new Properties(); - } - - return properties; + return (properties != null ? properties : (properties = new Properties())); } @Override public Cache getObject() throws Exception { - init(); - return cache; + return init(); } @Override @@ -909,27 +1026,4 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, return lazyInitialize; } - /* (non-Javadoc) */ - protected void postProcessPropertiesBeforeInitialization(Properties gemfireProperties) { - if (GemfireUtils.isGemfireVersion8OrAbove()) { - gemfireProperties.setProperty("disable-auto-reconnect", String.valueOf( - !Boolean.TRUE.equals(getEnableAutoReconnect()))); - gemfireProperties.setProperty("use-cluster-configuration", String.valueOf( - Boolean.TRUE.equals(getUseClusterConfiguration()))); - } - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() throws Exception { - postProcessPropertiesBeforeInitialization(getProperties()); - - if (!isLazyInitialize()) { - 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 0ee55b72..90ac33c1 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,6 +41,7 @@ import com.gemstone.gemfire.pdx.PdxSerializer; * @author Lyndon Adams * @author John Blum */ +@SuppressWarnings("unused") public class ClientCacheFactoryBean extends CacheFactoryBean { /** @@ -53,14 +53,13 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { 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) { @@ -79,11 +78,16 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { } } - 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 clientCacheFactory = (ClientCacheFactory) factory; @@ -107,95 +111,99 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { protected GemFireCache fetchCache() { return ClientCacheFactory.getAnyInstance(); } - + + /** + * 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)); + } + + /** + * 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 (localPool == null) { - if (StringUtils.hasText(poolName)) { - localPool = PoolManager.find(poolName); - } - - // Bind this client cache to a pool that hasn't been created yet. + localPool = PoolManager.find(poolName); + if (localPool == null) { - PoolFactoryBean.connectToTemporaryDs(this.properties); - } - - if (StringUtils.hasText(poolName)) { try { - getBeanFactory().isTypeMatch(poolName, Pool.class); - localPool = getBeanFactory().getBean(poolName, Pool.class); + 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(); + } } catch (Exception e) { - String message = String.format("No bean found with name '%1$s' of type '%2$s'.%3$s", poolName, - Pool.class.getName(), (GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME.equals(poolName) - ? " A client cache requires a pool." : "")); - - throw new BeanInitializationException(message); + 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); } } - else { - if (log.isDebugEnabled()) { - log.debug("Checking for a unique pool..."); - } - - localPool = getBeanFactory().getBean(Pool.class); - this.poolName = localPool.getName(); - } - } - if (localPool != null) { - // copy the pool settings - this way if the pool is not found, at - // least the cache will have a similar config - clientCacheFactory.setPoolFreeConnectionTimeout(localPool.getFreeConnectionTimeout()); - clientCacheFactory.setPoolIdleTimeout(localPool.getIdleTimeout()); - clientCacheFactory.setPoolLoadConditioningInterval(localPool.getLoadConditioningInterval()); - clientCacheFactory.setPoolMaxConnections(localPool.getMaxConnections()); - clientCacheFactory.setPoolMinConnections(localPool.getMinConnections()); - clientCacheFactory.setPoolMultiuserAuthentication(localPool.getMultiuserAuthentication()); - clientCacheFactory.setPoolPingInterval(localPool.getPingInterval()); - clientCacheFactory.setPoolPRSingleHopEnabled(localPool.getPRSingleHopEnabled()); - clientCacheFactory.setPoolReadTimeout(localPool.getReadTimeout()); - clientCacheFactory.setPoolRetryAttempts(localPool.getRetryAttempts()); - clientCacheFactory.setPoolServerGroup(localPool.getServerGroup()); - clientCacheFactory.setPoolSocketBufferSize(localPool.getSocketBufferSize()); - clientCacheFactory.setPoolStatisticInterval(localPool.getStatisticInterval()); - clientCacheFactory.setPoolSubscriptionAckInterval(localPool.getSubscriptionAckInterval()); - clientCacheFactory.setPoolSubscriptionEnabled(localPool.getSubscriptionEnabled()); - clientCacheFactory.setPoolSubscriptionMessageTrackingTimeout(localPool.getSubscriptionMessageTrackingTimeout()); - clientCacheFactory.setPoolSubscriptionRedundancy(localPool.getSubscriptionRedundancy()); - clientCacheFactory.setPoolThreadLocalConnections(localPool.getThreadLocalConnections()); + return localPool; + } - List locators = localPool.getLocators(); + /** + * 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()); - if (locators != null) { - for (InetSocketAddress socketAddress : locators) { - clientCacheFactory.addPoolLocator(socketAddress.getHostName(), socketAddress.getPort()); - } + for (InetSocketAddress socketAddress : nullSafeCollection(pool.getLocators())) { + clientCacheFactory.addPoolLocator(socketAddress.getHostName(), socketAddress.getPort()); } - List servers = localPool.getServers(); - - if (servers != null) { - for (InetSocketAddress socketAddress : servers) { - clientCacheFactory.addPoolServer(socketAddress.getHostName(), socketAddress.getPort()); - } + for (InetSocketAddress socketAddress : nullSafeCollection(pool.getServers())) { + clientCacheFactory.addPoolServer(socketAddress.getHostName(), socketAddress.getPort()); } } } @Override - protected void applyPdxOptions(Object factory) { + protected void setPdxOptions(Object factory) { if (factory instanceof ClientCacheFactory) { new PdxOptions((ClientCacheFactory) factory).run(); } } - @Override - protected void postProcessPropertiesBeforeInitialization(final Properties gemfireProperties) { - } - /** * Inform the GemFire cluster that this client cache is ready to receive events. */ @@ -228,7 +236,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { * @param pool the GemFire pool used by the Client Cache to obtain connections to the GemFire cluster. */ public void setPool(Pool pool) { - Assert.notNull(pool, "pool cannot be null"); + Assert.notNull(pool, "The GemFire Pool must not be null!"); this.pool = pool; } @@ -238,7 +246,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { * @param poolName set the name of the GemFire Pool used by the GemFire Client Cache. */ public void setPoolName(String poolName) { - Assert.hasText(poolName, "pool name is required"); + Assert.hasText(poolName, "The Pool 'name' is required!"); this.poolName = poolName; } 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 a42b2ab6..6f97656a 100644 --- a/src/main/java/org/springframework/data/gemfire/client/ClientRegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/ClientRegionFactoryBean.java @@ -91,63 +91,58 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean @Override @SuppressWarnings("deprecation") protected Region lookupFallback(GemFireCache cache, String regionName) throws Exception { - Assert.isTrue(cache instanceof ClientCache, String.format("Unable to create regions from %1$s", cache)); + 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."); + Assert.isTrue(((GemFireCacheImpl) cache).isClient(), "A ClientCache 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 + // map Region attributes onto the ClientRegionFactory... if (attributes != null) { - factory.setCloningEnabled(attributes.getCloningEnabled()); - factory.setCompressor(attributes.getCompressor()); - 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.setCompressor(attributes.getCompressor()); + 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); - } - else { - Pool pool = beanFactory.getBean(Pool.class); - factory.setPoolName(pool.getName()); + clientRegionFactory.setPoolName(poolName); } 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) { @@ -193,7 +188,6 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean resolvedShortcut = (isPersistent() ? ClientRegionShortcut.LOCAL_PERSISTENT : ClientRegionShortcut.LOCAL); } - } // NOTE the ClientRegionShortcut and Persistent attribute will be compatible if the shortcut was derived from @@ -471,15 +465,6 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean this.dataPolicy = dataPolicy; } - /** - * Sets the name of disk store to use for overflow and persistence - * - * @param diskStoreName a String specifying the 'name' of the client Region Disk Store. - */ - public void setDiskStoreName(String diskStoreName) { - this.diskStoreName = diskStoreName; - } - /** * An alternate way to set the Data Policy, using the String name of the enumerated value. * @@ -488,12 +473,22 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean * @see #setDataPolicy(com.gemstone.gemfire.cache.DataPolicy) * @deprecated use setDataPolicy(:DataPolicy) instead. */ + @Deprecated public void setDataPolicyName(String dataPolicyName) { - final DataPolicy resolvedDataPolicy = new DataPolicyConverter().convert(dataPolicyName); + DataPolicy resolvedDataPolicy = new DataPolicyConverter().convert(dataPolicyName); Assert.notNull(resolvedDataPolicy, String.format("Data Policy '%1$s' is invalid.", dataPolicyName)); setDataPolicy(resolvedDataPolicy); } + /** + * Sets the name of disk store to use for overflow and persistence + * + * @param diskStoreName a String specifying the 'name' of the client Region Disk Store. + */ + public void setDiskStoreName(String diskStoreName) { + this.diskStoreName = diskStoreName; + } + protected boolean isPersistentUnspecified() { return (persistent == null); } 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..2a059335 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,23 +178,52 @@ 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()); + } + + /* (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; + } + + public void setBeanName(String name) { + this.beanName = name; } /** @@ -218,189 +235,95 @@ public class PoolFactoryBean implements FactoryBean, InitializingBean, } /** - * @param locators - * the locators to set + * @param pool + * the pool to set */ - public void setLocators(Collection locators) { - this.locators = locators; + public void setPool(Pool pool) { + this.pool = pool; } - /** - * @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 setKeepAlive(boolean keepAlive) { + this.keepAlive = keepAlive; + } + + public void setLocators(Collection locators) { + this.locators = locators; + } + 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; - } - - public void setBeanFactory(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - /** - * @param multiUserAuthentication - * the multiUserAuthentication to set - */ public void setMultiUserAuthentication(boolean multiUserAuthentication) { this.multiUserAuthentication = multiUserAuthentication; } - /** - * @param prSingleHopEnabled - * the prSingleHopEnabled to set - */ + public void setPingInterval(long pingInterval) { + this.pingInterval = pingInterval; + } + 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 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 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 6dfcfcbe..bcce9372 100644 --- a/src/main/java/org/springframework/data/gemfire/config/GemfireConstants.java +++ b/src/main/java/org/springframework/data/gemfire/config/GemfireConstants.java @@ -26,7 +26,7 @@ public interface GemfireConstants { static final String DEFAULT_GEMFIRE_CACHE_NAME = "gemfireCache"; static final String DEFAULT_GEMFIRE_FUNCTION_SERVICE_NAME = "gemfireFunctionService"; - static final String DEFAULT_GEMFIRE_POOL_NAME = "gemfirePool"; + static final String DEFAULT_GEMFIRE_POOL_NAME = "DEFAULT"; static final String DEFAULT_GEMFIRE_TRANSACTION_MANAGER_NAME = "gemfireTransactionManager"; @Deprecated 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..d65e9c81 100644 --- a/src/main/java/org/springframework/data/gemfire/config/PoolParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/PoolParser.java @@ -32,10 +32,11 @@ import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; /** - * Parser for <pool;gt; definitions. + * Parser for GFE <pool;gt; bean definitions. * * @author Costin Leau * @author David Turanski + * @author John Blum */ class PoolParser extends AbstractSimpleBeanDefinitionParser { @@ -47,6 +48,7 @@ class PoolParser extends AbstractSimpleBeanDefinitionParser { @Override protected void postProcess(BeanDefinitionBuilder builder, Element element) { List subElements = DomUtils.getChildElements(element); + ManagedList locators = new ManagedList(subElements.size()); ManagedList servers = new ManagedList(subElements.size()); @@ -71,30 +73,42 @@ class PoolParser extends AbstractSimpleBeanDefinitionParser { } } - private Object parseServer(Element subElement) { - return parseConnection(subElement); + /* (non-Javadoc) */ + private BeanDefinition parseConnection(Element element) { + BeanDefinitionBuilder inetSocketAddressBuilder = BeanDefinitionBuilder.genericBeanDefinition( + InetSocketAddress.class); + + inetSocketAddressBuilder.addConstructorArgValue(element.getAttribute("host")); + inetSocketAddressBuilder.addConstructorArgValue(element.getAttribute("port")); + + return inetSocketAddressBuilder.getBeanDefinition(); } + /* (non-Javadoc) */ 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(); + /* (non-Javadoc) */ + 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 + + String id = super.resolveId(element, definition, parserContext); + + if (!StringUtils.hasText(id)) { + id = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME; + // for backward compatibility + 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/RegionLookupIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/RegionLookupIntegrationTests.java index 56fb6d5a..68fa846c 100644 --- a/src/test/java/org/springframework/data/gemfire/RegionLookupIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/RegionLookupIntegrationTests.java @@ -49,7 +49,8 @@ import com.gemstone.gemfire.cache.Scope; public class RegionLookupIntegrationTests { @BeforeClass - public static void preTestSuiteSetup() { + @SuppressWarnings("deprecation") + public static void testSuiteSetup() { ForkUtil.startCacheServer(SpringCacheServerProcess.class.getName() + " " + "/org/springframework/data/gemfire/RegionLookupIntegrationTests-server-context.xml"); } 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..0e24809c 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; @@ -33,22 +34,23 @@ import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.client.ClientCache; /** - * * @author David Turanski - * + * @author John Blum */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "client-cache.xml", initializers = GemfireTestApplicationContextInitializer.class) +@SuppressWarnings("unused") public class ClientCacheTest { - @Resource(name = "challengeQuestionsRegion") - Region region; @Autowired - ClientCache cache; + private ClientCache cache; + + @Resource(name = "challengeQuestionsRegion") + private Region region; @Test - public void test() { - assertEquals("gemfirePool", region.getAttributes().getPoolName()); + public void testPoolName() { + assertEquals(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, region.getAttributes().getPoolName()); } @Test @@ -58,4 +60,5 @@ public class ClientCacheTest { ctx.close(); assertFalse(cache.isClosed()); } + } 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..4e1e2fb6 100644 --- a/src/test/java/org/springframework/data/gemfire/client/ClientRegionFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/ClientRegionFactoryBeanTest.java @@ -21,21 +21,33 @@ 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; import com.gemstone.gemfire.cache.client.Pool; +import com.gemstone.gemfire.compression.Compressor; /** * @author David Turanski @@ -56,28 +68,185 @@ 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.getCompressor()).thenReturn(mock(Compressor.class)); + 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)).setCompressor(any(Compressor.class)); + 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 @@ -93,15 +262,24 @@ public class ClientRegionFactoryBeanTest { try { factoryBean.setDataPolicyName("INVALID"); } - catch (IllegalArgumentException e) { - assertEquals("Data Policy 'INVALID' is invalid.", e.getMessage()); - throw e; + catch (IllegalArgumentException expected) { + assertEquals("Data Policy 'INVALID' is invalid.", expected.getMessage()); + throw expected; } finally { assertNull(TestUtils.readField("dataPolicy", factoryBean)); } } + @Test + public void testIsPersistent() { + assertFalse(factoryBean.isPersistent()); + factoryBean.setPersistent(false); + assertFalse(factoryBean.isPersistent()); + factoryBean.setPersistent(true); + assertTrue(factoryBean.isPersistent()); + } + @Test public void testIsPersistentUnspecified() { assertTrue(factoryBean.isPersistentUnspecified()); @@ -113,15 +291,6 @@ public class ClientRegionFactoryBeanTest { assertFalse(factoryBean.isPersistentUnspecified()); } - @Test - public void testIsPersistent() { - assertFalse(factoryBean.isPersistent()); - factoryBean.setPersistent(false); - assertFalse(factoryBean.isPersistent()); - factoryBean.setPersistent(true); - assertTrue(factoryBean.isPersistent()); - } - @Test public void testIsNotPersistent() { assertFalse(factoryBean.isNotPersistent()); @@ -238,9 +407,10 @@ public class ClientRegionFactoryBeanTest { factoryBean.resolveClientRegionShortcut(); } - catch (IllegalArgumentException e) { - assertEquals("Client Region Shortcut 'CACHING_PROXY' is invalid when persistent is true.", e.getMessage()); - throw e; + catch (IllegalArgumentException expected) { + assertEquals("Client Region Shortcut 'CACHING_PROXY' is invalid when persistent is true.", + expected.getMessage()); + throw expected; } } @@ -264,9 +434,10 @@ public class ClientRegionFactoryBeanTest { factoryBean.resolveClientRegionShortcut(); } - catch (IllegalArgumentException e) { - assertEquals("Client Region Shortcut 'LOCAL_PERSISTENT' is invalid when persistent is false.", e.getMessage()); - throw e; + catch (IllegalArgumentException expected) { + assertEquals("Client Region Shortcut 'LOCAL_PERSISTENT' is invalid when persistent is false.", + expected.getMessage()); + throw expected; } } @@ -310,9 +481,9 @@ public class ClientRegionFactoryBeanTest { factoryBean.resolveClientRegionShortcut(); } - catch (IllegalArgumentException e) { - assertEquals("Data Policy 'NORMAL' is invalid when persistent is true.", e.getMessage()); - throw e; + catch (IllegalArgumentException expected) { + assertEquals("Data Policy 'NORMAL' is invalid when persistent is true.", expected.getMessage()); + throw expected; } } @@ -336,9 +507,9 @@ public class ClientRegionFactoryBeanTest { factoryBean.resolveClientRegionShortcut(); } - catch (IllegalArgumentException e) { - assertEquals("Data Policy 'PERSISTENT_REPLICATE' is invalid when persistent is false.", e.getMessage()); - throw e; + catch (IllegalArgumentException expected) { + assertEquals("Data Policy 'PERSISTENT_REPLICATE' is invalid when persistent is false.", expected.getMessage()); + throw expected; } } 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 e116f859..f91033bb 100644 --- a/src/test/java/org/springframework/data/gemfire/config/CacheNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/CacheNamespaceTest.java @@ -177,7 +177,7 @@ public class CacheNamespaceTest{ CacheFactoryBean cacheFactoryBean = context.getBean("&no-bean-factory-locator", CacheFactoryBean.class); - assertThat(ReflectionTestUtils.getField(cacheFactoryBean, "factoryLocator"), is(nullValue())); + assertThat(ReflectionTestUtils.getField(cacheFactoryBean, "beanFactoryLocator"), is(nullValue())); GemfireBeanFactoryLocator beanFactoryLocator = new GemfireBeanFactoryLocator(); 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..44493808 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; @@ -40,52 +41,60 @@ import com.gemstone.gemfire.cache.client.PoolManager; * @author Costin Leau */ @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 177134b9..9107618f 100644 --- a/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java +++ b/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java @@ -33,7 +33,7 @@ public class MockCacheFactoryBean extends CacheFactoryBean { public MockCacheFactoryBean(CacheFactoryBean cacheFactoryBean) { this(); if (cacheFactoryBean != null) { - this.factoryLocator = cacheFactoryBean.getBeanFactoryLocator(); + this.beanFactoryLocator = cacheFactoryBean.getBeanFactoryLocator(); this.lazyInitialize = cacheFactoryBean.isLazyInitialize(); this.beanClassLoader = cacheFactoryBean.getBeanClassLoader(); this.beanFactory = cacheFactoryBean.getBeanFactory(); 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 bd26b303..e856a84b 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.beanClassLoader = cacheFactoryBean.getBeanClassLoader(); this.beanFactory = cacheFactoryBean.getBeanFactory(); this.beanName = cacheFactoryBean.getBeanName(); 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..48024c42 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,24 @@ - - - - - - + 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 + + + + + + + +