diff --git a/pom.xml b/pom.xml index 1e7b251d..d1788b32 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.springframework.data spring-data-geode - 2.1.0.BUILD-SNAPSHOT + 2.1.0.DATAGEODE-100-SNAPSHOT Spring Data Geode diff --git a/src/main/asciidoc/reference/bootstrap-annotations.adoc b/src/main/asciidoc/reference/bootstrap-annotations.adoc index 8187beeb..af512b4c 100644 --- a/src/main/asciidoc/reference/bootstrap-annotations.adoc +++ b/src/main/asciidoc/reference/bootstrap-annotations.adoc @@ -350,17 +350,17 @@ Building on our examples above, the client's `application.properties` would defi [source, java] ---- spring.data.gemfire.cache.log-level=info -spring.data.gemfire.pool.venus.servers=venus[48484] -spring.data.gemfire.pool.venus.max-connections=200 -spring.data.gemfire.pool.venus.min-connections=50 -spring.data.gemfire.pool.venus.ping-interval=15000 -spring.data.gemfire.pool.venus.pr-single-hop-enabled=true -spring.data.gemfire.pool.venus.read-timeout=20000 -spring.data.gemfire.pool.venus.subscription-enabled=true -spring.data.gemfire.pool.saturn.locators=skullbox[20668] -spring.data.gemfire.pool.saturn.subscription-enabled=true -spring.data.gemfire.pool.neptune.servers=saturn[41414],neptune[42424] -spring.data.gemfire.pool.neptune.min-connections=25 +spring.data.gemfire.pool.Venus.servers=venus[48484] +spring.data.gemfire.pool.Venus.max-connections=200 +spring.data.gemfire.pool.Venus.min-connections=50 +spring.data.gemfire.pool.Venus.ping-interval=15000 +spring.data.gemfire.pool.Venus.pr-single-hop-enabled=true +spring.data.gemfire.pool.Venus.read-timeout=20000 +spring.data.gemfire.pool.Venus.subscription-enabled=true +spring.data.gemfire.pool.Saturn.locators=skullbox[20668] +spring.data.gemfire.pool.Saturn.subscription-enabled=true +spring.data.gemfire.pool.Neptune.servers=saturn[41414],neptune[42424] +spring.data.gemfire.pool.Neptune.min-connections=25 ---- And, the server's application.properties would define... @@ -383,9 +383,9 @@ Then, we can simplify the `@ClientCacheApplication` class to... @SpringBootApplication @ClientCacheApplication @EnablePools(pools = { - @EnablePool(name = "VenusPool"), - @EnablePool(name = "SaturnPool"), - @EnablePool(name = "NeptunePool") + @EnablePool(name = "Venus"), + @EnablePool(name = "Saturn"), + @EnablePool(name = "Neptune") }) class ClientApplication { .. } ---- diff --git a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java index d9b6352f..1239bb80 100644 --- a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java @@ -29,8 +29,8 @@ import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newR import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -72,12 +72,13 @@ import org.springframework.util.StringUtils; * Spring {@link FactoryBean} used to construct, configure and initialize a Pivotal GemFire/Apache Geode * {@link Cache peer cache). * - * Allows either retrieval of an existing, opened {@link Cache} or creation of a new {@link Cache}. + * Allows either retrieval of an existing, open {@link Cache} or creation of a new {@link Cache}. * * This class implements the {@link PersistenceExceptionTranslator} interface and is auto-detected by Spring's * {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor} for AOP-based translation - * of native persistent store exceptions to Spring's {@link DataAccessException} hierarchy. Therefore, the presence - * of this class automatically enables a {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor} + * of native persistent data store exceptions to Spring's {@link DataAccessException} hierarchy. Therefore, the presence + * of this class automatically enables a + * {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor} * to translate Pivotal GemFire/Apache Geode exceptions appropriately. * * @author Costin Leau @@ -119,10 +120,10 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport private Boolean pdxReadSerialized; private Boolean useClusterConfiguration; - private GemFireCache cache; - private CacheFactoryInitializer cacheFactoryInitializer; + private GemFireCache cache; + private DynamicRegionSupport dynamicRegionSupport; private Float criticalHeapPercentage; @@ -139,7 +140,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport private Integer messageSyncInterval; private Integer searchTimeout; - private List peerCacheConfigurers = Collections.emptyList(); + private List peerCacheConfigurers = new ArrayList<>(); private List jndiDataSources; @@ -165,13 +166,65 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport * * @throws Exception if initialization fails. * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + * @see #applyCacheConfigurers() * @see #initBeanFactoryLocator() - * @see #postProcessBeforeCacheInitialization(Properties) */ @Override public void afterPropertiesSet() throws Exception { + applyCacheConfigurers(); initBeanFactoryLocator(); - postProcessBeforeCacheInitialization(resolveProperties()); + } + + /** + * Applies the composite {@link PeerCacheConfigurer PeerCacheConfigurers} to this {@link CacheFactoryBean} + * before creating the {@link Cache peer Cache}. + * + * @see #getCompositePeerCacheConfigurer() + * @see #applyPeerCacheConfigurers(PeerCacheConfigurer...) + */ + protected void applyCacheConfigurers() { + + PeerCacheConfigurer autoReconnectClusterConfigurationConfigurer = (beanName, cacheFactoryBean) -> { + + Properties gemfireProperties = resolveProperties(); + + gemfireProperties.setProperty("disable-auto-reconnect", + String.valueOf(!Boolean.TRUE.equals(getEnableAutoReconnect()))); + + gemfireProperties.setProperty("use-cluster-configuration", + String.valueOf(Boolean.TRUE.equals(getUseClusterConfiguration()))); + }; + + this.peerCacheConfigurers.add(autoReconnectClusterConfigurationConfigurer); + + applyPeerCacheConfigurers(getCompositePeerCacheConfigurer()); + } + + /** + * Applies the given array of {@link PeerCacheConfigurer PeerCacheConfigurers} to this {@link CacheFactoryBean}. + * + * @param peerCacheConfigurers array of {@link PeerCacheConfigurer PeerCacheConfigurers} applied to + * this {@link CacheFactoryBean}. + * @see org.springframework.data.gemfire.config.annotation.PeerCacheConfigurer + * @see #applyPeerCacheConfigurers(Iterable) + */ + protected void applyPeerCacheConfigurers(PeerCacheConfigurer... peerCacheConfigurers) { + applyPeerCacheConfigurers(Arrays.asList(nullSafeArray(peerCacheConfigurers, PeerCacheConfigurer.class))); + } + + /** + * Applies the given {@link Iterable} of {@link PeerCacheConfigurer PeerCacheConfigurers} + * to this {@link CacheFactoryBean}. + * + * @param peerCacheConfigurers {@link Iterable} of {@link PeerCacheConfigurer PeerCacheConfigurers} + * applied to this {@link CacheFactoryBean}. + * @see org.springframework.data.gemfire.config.annotation.PeerCacheConfigurer + * @see java.lang.Iterable + * @see #applyPeerCacheConfigurers(PeerCacheConfigurer...) + */ + protected void applyPeerCacheConfigurers(Iterable peerCacheConfigurers) { + stream(nullSafeIterable(peerCacheConfigurers).spliterator(), false) + .forEach(clientCacheConfigurer -> clientCacheConfigurer.configure(getBeanName(), this)); } /** @@ -184,64 +237,13 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport * @see #getBeanFactory() * @see #getBeanName() */ - private void initBeanFactoryLocator() { - if (isUseBeanFactoryLocator() && getBeanFactoryLocator() == null) { + void initBeanFactoryLocator() { + + if (isUseBeanFactoryLocator() && this.beanFactoryLocator == null) { this.beanFactoryLocator = newBeanFactoryLocator(getBeanFactory(), getBeanName()); } } - /** - * Post processes this {@link CacheFactoryBean} before cache initialization. - * - * This is also the point at which any configured {@link PeerCacheConfigurer} beans are called. - * - * @param gemfireProperties {@link Properties} used to configure Pivotal GemFire/Apache Geode. - * @see org.springframework.data.gemfire.config.annotation.PeerCacheConfigurer - * @see java.util.Properties - */ - protected void postProcessBeforeCacheInitialization(Properties gemfireProperties) { - - gemfireProperties.setProperty("disable-auto-reconnect", String.valueOf( - !Boolean.TRUE.equals(getEnableAutoReconnect()))); - - gemfireProperties.setProperty("use-cluster-configuration", String.valueOf( - Boolean.TRUE.equals(getUseClusterConfiguration()))); - - applyPeerCacheConfigurers(); - } - - /* (non-Javadoc) */ - private void applyPeerCacheConfigurers() { - applyPeerCacheConfigurers(getCompositePeerCacheConfigurer()); - } - - /** - * Null-safe operation to apply the given array of {@link PeerCacheConfigurer PeerCacheConfigurers} - * to this {@link CacheFactoryBean}. - * - * @param peerCacheConfigurers array of {@link PeerCacheConfigurer PeerCacheConfigurers} applied to - * this {@link CacheFactoryBean}. - * @see org.springframework.data.gemfire.config.annotation.PeerCacheConfigurer - * @see #applyPeerCacheConfigurers(Iterable) - */ - protected void applyPeerCacheConfigurers(PeerCacheConfigurer... peerCacheConfigurers) { - applyPeerCacheConfigurers(Arrays.asList(nullSafeArray(peerCacheConfigurers, PeerCacheConfigurer.class))); - } - - /** - * Null-safe operation to apply the given {@link Iterable} of {@link PeerCacheConfigurer PeerCacheConfigurers} - * to this {@link CacheFactoryBean}. - * - * @param peerCacheConfigurers {@link Iterable} of {@link PeerCacheConfigurer PeerCacheConfigurers} - * applied to this {@link CacheFactoryBean}. - * @see org.springframework.data.gemfire.config.annotation.PeerCacheConfigurer - * @see java.lang.Iterable - */ - protected void applyPeerCacheConfigurers(Iterable peerCacheConfigurers) { - stream(nullSafeIterable(peerCacheConfigurers).spliterator(), false) - .forEach(clientCacheConfigurer -> clientCacheConfigurer.configure(getBeanName(), this)); - } - /** * Initializes the {@link Cache}. * @@ -257,14 +259,15 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport ClassLoader currentThreadContextClassLoader = Thread.currentThread().getContextClassLoader(); try { - // use bean ClassLoader to load Spring configured, Pivotal GemFire/Apache Geode classes + // Use Spring Bean ClassLoader to load Spring configured, Pivotal GemFire/Apache Geode classes Thread.currentThread().setContextClassLoader(getBeanClassLoader()); setCache(postProcess(resolveCache())); - Optional.ofNullable(this.getCache()).ifPresent(cache -> { + Optional.ofNullable(getCache()).ifPresent(cache -> { - Optional.ofNullable(cache.getDistributedSystem()).map(DistributedSystem::getDistributedMember) + Optional.ofNullable(cache.getDistributedSystem()) + .map(DistributedSystem::getDistributedMember) .ifPresent(member -> logInfo(() -> 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]"), @@ -279,8 +282,8 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport return getCache(); } - catch (Exception e) { - throw newRuntimeException(e, "Error occurred when initializing peer cache"); + catch (Exception cause) { + throw newRuntimeException(cause, "Error occurred when initializing peer cache"); } finally { Thread.currentThread().setContextClassLoader(currentThreadContextClassLoader); @@ -298,19 +301,24 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport * @see #fetchCache() * @see #resolveProperties() * @see #createFactory(java.util.Properties) - * @see #prepareFactory(Object) + * @see #configureFactory(Object) * @see #createCache(Object) */ @SuppressWarnings("unchecked") protected T resolveCache() { + try { + this.cacheResolutionMessagePrefix = "Found existing"; + return (T) fetchCache(); } - catch (CacheClosedException ex) { + catch (CacheClosedException cause) { + this.cacheResolutionMessagePrefix = "Created new"; initDynamicRegionFactory(); - return (T) createCache(prepareFactory(initializeFactory(createFactory(resolveProperties())))); + + return (T) createCache(postProcess(configureFactory(initializeFactory(createFactory(resolveProperties()))))); } } @@ -353,7 +361,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport /** * Constructs a new instance of {@link CacheFactory} initialized with the given Pivotal GemFire/Apache Geode - * {@link Properties} used to create an instance of a {@link Cache}. + * {@link Properties} used to construct, configure and initialize an instance of a {@link Cache}. * * @param gemfireProperties {@link Properties} used by the {@link CacheFactory} to configure the {@link Cache}. * @return a new instance of {@link CacheFactory} initialized with the given Pivotal GemFire/Apache Geode @@ -366,11 +374,12 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport } /** - * Initializes the given cache factory with the configured {@link CacheFactoryInitializer}. + * Initializes the given {@link CacheFactory} with the configured {@link CacheFactoryInitializer}. * - * @param factory cache factory to initialize; may be {@literal null}. - * @return the given cache factory. + * @param factory {@link CacheFactory} to initialize; may be {@literal null}. + * @return the initialized {@link CacheFactory}. * @see org.springframework.data.gemfire.CacheFactoryBean.CacheFactoryInitializer#initialize(Object) + * @see org.apache.geode.cache.CacheFactory * @see #getCacheFactoryInitializer() */ @Nullable @@ -383,16 +392,17 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport } /** - * Prepares and initializes the {@link CacheFactory} used to create the {@link Cache}. + * Configures the {@link CacheFactory} used to create the {@link Cache}. * * Sets PDX options specified by the user. * * @param factory {@link CacheFactory} used to create the {@link Cache}. - * @return the prepared and initialized {@link CacheFactory}. - * @see #initializePdx(CacheFactory) + * @return the configured {@link CacheFactory}. + * @see org.apache.geode.cache.CacheFactory + * @see #configurePdx(CacheFactory) */ - protected Object prepareFactory(Object factory) { - return initializePdx((CacheFactory) factory); + protected Object configureFactory(Object factory) { + return configurePdx((CacheFactory) factory); } /** @@ -402,7 +412,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport * @return the given {@link CacheFactory}. * @see org.apache.geode.cache.CacheFactory */ - private CacheFactory initializePdx(CacheFactory cacheFactory) { + private CacheFactory configurePdx(CacheFactory cacheFactory) { Optional.ofNullable(getPdxSerializer()).ifPresent(cacheFactory::setPdxSerializer); @@ -419,17 +429,28 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport } /** - * Creates a new {@link Cache} instance using the provided factory. + * Post processes the {@link CacheFactory} used to create the {@link Cache}. * - * @param parameterized {@link Class} type extension of {@link GemFireCache}. + * @param factory {@link CacheFactory} used to create the {@link Cache}. + * @return the post processed {@link CacheFactory}. + * @see org.apache.geode.cache.CacheFactory + */ + protected Object postProcess(Object factory) { + return factory; + } + + /** + * Creates a new {@link Cache} instance using the provided {@link Object factory}. + * + * @param {@link Class sub-type} of {@link GemFireCache}. * @param factory instance of {@link CacheFactory}. - * @return a new instance of {@link Cache} created by the provided factory. + * @return a new instance of {@link Cache} created by the provided {@link Object factory}. * @see org.apache.geode.cache.CacheFactory#create() * @see org.apache.geode.cache.GemFireCache */ @SuppressWarnings("unchecked") protected T createCache(Object factory) { - return (T) Optional.ofNullable(getCache()).orElseGet(((CacheFactory) factory)::create); + return (T) ((CacheFactory) factory).create(); } /** @@ -450,16 +471,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport @SuppressWarnings("all") protected T postProcess(T cache) { - // load cache.xml Resource and initialize the cache - Optional.ofNullable(getCacheXml()).ifPresent(cacheXml -> { - try { - logDebug("Initializing cache with [%s]", cacheXml); - cache.loadCacheXml(cacheXml.getInputStream()); - } - catch (IOException e) { - throw newRuntimeException(e, "Failed to load cache.xml [%s]", cacheXml); - } - }); + loadCacheXml(cache); Optional.ofNullable(getCopyOnRead()).ifPresent(cache::setCopyOnRead); @@ -473,20 +485,34 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport configureHeapPercentages(cache); configureOffHeapPercentages(cache); - registerJndiDataSources(); + registerJndiDataSources(cache); registerTransactionListeners(cache); registerTransactionWriter(cache); return cache; } - /* (non-Javadoc) */ - private boolean isHeapPercentageValid(Float heapPercentage) { - return (heapPercentage >= 0.0f && heapPercentage <= 100.0f); + private T loadCacheXml(T cache) { + + // Load cache.xml Resource and initialize the cache + Optional.ofNullable(getCacheXml()).ifPresent(cacheXml -> { + try { + logDebug("Initializing cache with [%s]", cacheXml); + cache.loadCacheXml(cacheXml.getInputStream()); + } + catch (IOException cause) { + throw newRuntimeException(cause, "Failed to load cache.xml [%s]", cacheXml); + } + }); + + return cache; } - /* (non-Javadoc) */ - private void configureHeapPercentages(GemFireCache cache) { + private boolean isHeapPercentageValid(Float heapPercentage) { + return heapPercentage >= 0.0f && heapPercentage <= 100.0f; + } + + private GemFireCache configureHeapPercentages(GemFireCache cache) { Optional.ofNullable(getCriticalHeapPercentage()).ifPresent(criticalHeapPercentage -> { @@ -503,10 +529,11 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport cache.getResourceManager().setEvictionHeapPercentage(evictionHeapPercentage); }); + + return cache; } - /* (non-Javadoc) */ - private void configureOffHeapPercentages(GemFireCache cache) { + private GemFireCache configureOffHeapPercentages(GemFireCache cache) { Optional.ofNullable(getCriticalOffHeapPercentage()).ifPresent(criticalOffHeapPercentage -> { @@ -523,10 +550,11 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport cache.getResourceManager().setEvictionOffHeapPercentage(evictionOffHeapPercentage); }); + + return cache; } - /* (non-Javadoc) */ - private void registerJndiDataSources() { + private GemFireCache registerJndiDataSources(GemFireCache cache) { nullSafeCollection(getJndiDataSources()).forEach(jndiDataSource -> { @@ -534,41 +562,30 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport JndiDataSourceType jndiDataSourceType = JndiDataSourceType.valueOfIgnoreCase(type); - Assert.notNull(jndiDataSourceType, String.format( - "'jndi-binding' 'type' [%1$s] is invalid; 'type' must be one of %2$s", type, - Arrays.toString(JndiDataSourceType.values()))); + Assert.notNull(jndiDataSourceType, + String.format("'jndi-binding' 'type' [%1$s] is invalid; 'type' must be one of %2$s", + type, Arrays.toString(JndiDataSourceType.values()))); jndiDataSource.getAttributes().put("type", jndiDataSourceType.getName()); JNDIInvoker.mapDatasource(jndiDataSource.getAttributes(), jndiDataSource.getProps()); }); + + return cache; } - /* (non-Javadoc) */ - private void registerTransactionListeners(GemFireCache cache) { + private GemFireCache registerTransactionListeners(GemFireCache cache) { + nullSafeCollection(getTransactionListeners()) .forEach(transactionListener -> cache.getCacheTransactionManager().addListener(transactionListener)); + + return cache; } - /* (non-Javadoc) */ - private void registerTransactionWriter(GemFireCache cache) { + private GemFireCache registerTransactionWriter(GemFireCache cache) { + Optional.ofNullable(getTransactionWriter()).ifPresent(it -> cache.getCacheTransactionManager().setWriter(it)); - } - /** - * Destroys the {@link Cache} bean on Spring container shutdown. - * - * @throws Exception if an error occurs while closing the cache. - * @see org.springframework.beans.factory.DisposableBean#destroy() - * @see #destroyBeanFactoryLocator() - * @see #close(GemFireCache) - * @see #isClose() - */ - @Override - public void destroy() throws Exception { - if (isClose()) { - close(fetchCache()); - destroyBeanFactoryLocator(); - } + return cache; } /** @@ -585,7 +602,25 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport .filter(it -> !it.isClosed()) .ifPresent(RegionService::close); - this.cache = null; + setCache(null); + } + + /** + * Destroys the {@link Cache} bean on Spring container shutdown. + * + * @throws Exception if an error occurs while closing the cache. + * @see org.springframework.beans.factory.DisposableBean#destroy() + * @see #destroyBeanFactoryLocator() + * @see #close(GemFireCache) + * @see #isClose() + */ + @Override + public void destroy() throws Exception { + + if (isClose()) { + close(fetchCache()); + destroyBeanFactoryLocator(); + } } /** @@ -613,7 +648,9 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport public DataAccessException translateExceptionIfPossible(RuntimeException exception) { if (exception instanceof IllegalArgumentException) { + DataAccessException wrapped = GemfireCacheUtils.convertQueryExceptions(exception); + // ignore conversion if generic exception is returned if (!(wrapped instanceof GemfireSystemException)) { return wrapped; @@ -702,11 +739,12 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport * @see #getCacheXml() */ private File getCacheXmlFile() { + try { return getCacheXml().getFile(); } - catch (Throwable e) { - throw newIllegalStateException(e, "Resource [%s] is not resolvable as a file", getCacheXml()); + catch (Throwable cause) { + throw newIllegalStateException(cause, "Resource [%s] is not resolvable as a file", getCacheXml()); } } @@ -716,9 +754,11 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport * @return boolean value indicating whether a {@link Resource cache.xml} {@link File} is present. * @see #getCacheXmlFile() */ + @SuppressWarnings("all") private boolean isCacheXmlAvailable() { + try { - return (getCacheXmlFile() != null); + return getCacheXmlFile() != null; } catch (Throwable ignore) { return false; @@ -736,7 +776,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport @Override @SuppressWarnings("all") public GemFireCache getObject() throws Exception { - return Optional.ofNullable(this.getCache()).orElseGet(this::init); + return Optional.ofNullable(getCache()).orElseGet(this::init); } /** @@ -752,26 +792,25 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport } /** - * Set the phase for the {@link Cache} bean in the lifecycle managed by the Spring container. + * Set the {@link CacheFactoryInitializer} that will be called to initialize the cache factory used to create + * the cache constructed by this {@link CacheFactoryBean}. * - * @param phase {@link Integer#TYPE int} value indicating the phase of this {@link Cache} bean - * in the lifecycle managed by the Spring container. - * @see org.springframework.context.Phased#getPhase() + * @param cacheFactoryInitializer {@link CacheFactoryInitializer} configured to initialize the cache factory. + * @see org.springframework.data.gemfire.CacheFactoryBean.CacheFactoryInitializer */ - protected void setPhase(int phase) { - this.phase = phase; + public void setCacheFactoryInitializer(CacheFactoryInitializer cacheFactoryInitializer) { + this.cacheFactoryInitializer = cacheFactoryInitializer; } /** - * Returns the configured phase of the {@link Cache} bean in the lifecycle managed by the Spring container. + * Return the {@link CacheFactoryInitializer} that will be called to initialize the cache factory used to create + * the cache constructed by this {@link CacheFactoryBean}. * - * @return an {@link Integer#TYPE int} value indicating the phase of this {@link Cache} bean in the lifecycle - * managed by the Spring container. - * @see org.springframework.context.Phased#getPhase() + * @return the {@link CacheFactoryInitializer} configured to initialize the cache factory. + * @see org.springframework.data.gemfire.CacheFactoryBean.CacheFactoryInitializer */ - @Override - public int getPhase() { - return this.phase; + public CacheFactoryInitializer getCacheFactoryInitializer() { + return this.cacheFactoryInitializer; } /** @@ -808,28 +847,6 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport return this.properties; } - /** - * Set the {@link CacheFactoryInitializer} that will be called to initialize the cache factory used to create - * the cache constructed by this {@link CacheFactoryBean}. - * - * @param cacheFactoryInitializer {@link CacheFactoryInitializer} configured to initialize the cache factory. - * @see org.springframework.data.gemfire.CacheFactoryBean.CacheFactoryInitializer - */ - public void setCacheFactoryInitializer(CacheFactoryInitializer cacheFactoryInitializer) { - this.cacheFactoryInitializer = cacheFactoryInitializer; - } - - /** - * Return the {@link CacheFactoryInitializer} that will be called to initialize the cache factory used to create - * the cache constructed by this {@link CacheFactoryBean}. - * - * @return the {@link CacheFactoryInitializer} configured to initialize the cache factory. - * @see org.springframework.data.gemfire.CacheFactoryBean.CacheFactoryInitializer - */ - public CacheFactoryInitializer getCacheFactoryInitializer() { - return this.cacheFactoryInitializer; - } - /** * Sets a value to indicate whether the cache will be closed on shutdown of the Spring container. * @@ -940,7 +957,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport * or not. */ public Boolean getEnableAutoReconnect() { - return enableAutoReconnect; + return this.enableAutoReconnect; } /** @@ -1057,6 +1074,29 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport return messageSyncInterval; } + /** + * Set the phase for the {@link Cache} bean in the lifecycle managed by the Spring container. + * + * @param phase {@link Integer#TYPE int} value indicating the phase of this {@link Cache} bean + * in the lifecycle managed by the Spring container. + * @see org.springframework.context.Phased#getPhase() + */ + protected void setPhase(int phase) { + this.phase = phase; + } + + /** + * Returns the configured phase of the {@link Cache} bean in the lifecycle managed by the Spring container. + * + * @return an {@link Integer#TYPE int} value indicating the phase of this {@link Cache} bean in the lifecycle + * managed by the Spring container. + * @see org.springframework.context.Phased#getPhase() + */ + @Override + public int getPhase() { + return this.phase; + } + /** * Set the disk store that is used for PDX meta data. Applicable on GemFire * 6.6 or higher. @@ -1164,7 +1204,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport * @see org.springframework.data.gemfire.config.annotation.PeerCacheConfigurer */ public void setPeerCacheConfigurers(List peerCacheConfigurers) { - this.peerCacheConfigurers = Optional.ofNullable(peerCacheConfigurers).orElseGet(Collections::emptyList); + Optional.ofNullable(peerCacheConfigurers).ifPresent(this.peerCacheConfigurers::addAll); } /** @@ -1279,9 +1319,9 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport * @see org.apache.geode.cache.client.ClientCacheFactory */ T initialize(T cacheFactory); + } - /* (non-Javadoc) */ public static class DynamicRegionSupport { private Boolean persistent = Boolean.TRUE; @@ -1323,23 +1363,25 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport } public void initializeDynamicRegionFactory() { - File localDiskDirectory = (this.diskDirectory != null ? new File(this.diskDirectory) : null); - DynamicRegionFactory.Config config = new DynamicRegionFactory.Config(localDiskDirectory, poolName, - persistent, registerInterest); + File localDiskDirectory = this.diskDirectory != null ? new File(this.diskDirectory) : null; + + DynamicRegionFactory.Config config = + new DynamicRegionFactory.Config(localDiskDirectory, this.poolName, this.persistent, + this.registerInterest); DynamicRegionFactory.get().open(config); } } - /* (non-Javadoc) */ public static class JndiDataSource { - private List props; + private List configProperties; + private Map attributes; public Map getAttributes() { - return attributes; + return this.attributes; } public void setAttributes(Map attributes) { @@ -1347,11 +1389,11 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport } public List getProps() { - return props; + return this.configProperties; } public void setProps(List props) { - this.props = props; + this.configProperties = props; } } } diff --git a/src/main/java/org/springframework/data/gemfire/ConfigurableRegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/ConfigurableRegionFactoryBean.java new file mode 100644 index 00000000..526a33b9 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/ConfigurableRegionFactoryBean.java @@ -0,0 +1,139 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire; + +import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; +import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeCollection; +import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeIterable; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.StreamSupport; + +import org.apache.geode.cache.Region; +import org.springframework.data.gemfire.client.ClientRegionFactoryBean; +import org.springframework.data.gemfire.config.annotation.RegionConfigurer; + +/** + * The ConfigurableRegionFactoryBean class... + * + * @author John Blum + * @see org.springframework.data.gemfire.RegionLookupFactoryBean + * @since 2.1.0 + */ +@SuppressWarnings("unused") +public abstract class ConfigurableRegionFactoryBean extends RegionLookupFactoryBean { + + private List regionConfigurers = Collections.emptyList(); + + private RegionConfigurer compositeRegionConfigurer = new RegionConfigurer() { + + @Override + public void configure(String beanName, ClientRegionFactoryBean bean) { + nullSafeCollection(regionConfigurers) + .forEach(regionConfigurer -> regionConfigurer.configure(beanName, bean)); + } + }; + + /** + * Returns a reference to the Composite {@link RegionConfigurer} used to apply additional configuration + * to this {@link ClientRegionFactoryBean} on Spring container initialization. + * + * @return the Composite {@link RegionConfigurer}. + * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer + */ + protected RegionConfigurer getCompositeRegionConfigurer() { + return this.compositeRegionConfigurer; + } + + /** + * Null-safe operation to set an array of {@link RegionConfigurer RegionConfigurers} used to apply + * additional configuration to this {@link ClientRegionFactoryBean} when using Annotation-based configuration. + * + * @param regionConfigurers array of {@link RegionConfigurer RegionConfigurers} used to apply + * additional configuration to this {@link ClientRegionFactoryBean}. + * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer + * @see #setRegionConfigurers(List) + */ + public void setRegionConfigurers(RegionConfigurer... regionConfigurers) { + setRegionConfigurers(Arrays.asList(nullSafeArray(regionConfigurers, RegionConfigurer.class))); + } + + /** + * Null-safe operation to set an {@link Iterable} of {@link RegionConfigurer RegionConfigurers} used to apply + * additional configuration to this {@link ClientRegionFactoryBean} when using Annotation-based configuration. + * + * @param regionConfigurers {@link Iterable} of {@link RegionConfigurer RegionConfigurers} used to apply + * additional configuration to this {@link ClientRegionFactoryBean}. + * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer + */ + public void setRegionConfigurers(List regionConfigurers) { + this.regionConfigurers = Optional.ofNullable(regionConfigurers).orElseGet(Collections::emptyList); + } + + /** + * Null-safe operation to apply the composite {@link RegionConfigurer RegionConfigurers} + * to this {@link ConfigurableRegionFactoryBean}. + * + * @param regionName {@link String} containing the name of the {@link Region}. + * to this {@link ConfigurableRegionFactoryBean}. + * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer + * @see #applyRegionConfigurers(String, Iterable) + * @see #getCompositeRegionConfigurer() + */ + protected void applyRegionConfigurers(String regionName) { + applyRegionConfigurers(regionName, getCompositeRegionConfigurer()); + } + + /** + * Null-safe operation to apply the given array of {@link RegionConfigurer RegionConfigurers} + * to this {@link ConfigurableRegionFactoryBean}. + * + * @param regionName {@link String} containing the name of the {@link Region}. + * @param regionConfigurers array of {@link RegionConfigurer RegionConfigurers} applied + * to this {@link ConfigurableRegionFactoryBean}. + * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer + * @see #applyRegionConfigurers(String, Iterable) + */ + protected void applyRegionConfigurers(String regionName, RegionConfigurer... regionConfigurers) { + applyRegionConfigurers(regionName, Arrays.asList(nullSafeArray(regionConfigurers, RegionConfigurer.class))); + } + + /** + * Null-safe operation to apply the given {@link Iterable} of {@link RegionConfigurer RegionConfigurers} + * to this {@link ConfigurableRegionFactoryBean}. + * + * @param regionName {@link String} containing the name of the {@link Region}. + * @param regionConfigurers {@link Iterable} of {@link RegionConfigurer RegionConfigurers} applied + * to this {@link ConfigurableRegionFactoryBean}. + * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer + * @see #applyRegionConfigurers(String, RegionConfigurer...) + */ + protected void applyRegionConfigurers(String regionName, Iterable regionConfigurers) { + + if (this instanceof RegionFactoryBean) { + StreamSupport.stream(nullSafeIterable(regionConfigurers).spliterator(), false) + .forEach(regionConfigurer -> regionConfigurer.configure(regionName, (RegionFactoryBean) this)); + } + else if (this instanceof ClientRegionFactoryBean) { + StreamSupport.stream(nullSafeIterable(regionConfigurers).spliterator(), false) + .forEach(regionConfigurer -> regionConfigurer.configure(regionName, (ClientRegionFactoryBean) this)); + } + } +} diff --git a/src/main/java/org/springframework/data/gemfire/LookupRegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/LookupRegionFactoryBean.java index 3984e1ef..adc0d032 100644 --- a/src/main/java/org/springframework/data/gemfire/LookupRegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/LookupRegionFactoryBean.java @@ -16,36 +16,38 @@ package org.springframework.data.gemfire; -import org.apache.geode.cache.AttributesMutator; +import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; + +import java.util.Arrays; +import java.util.Optional; + import org.apache.geode.cache.CacheListener; import org.apache.geode.cache.CacheLoader; import org.apache.geode.cache.CacheWriter; import org.apache.geode.cache.CustomExpiry; -import org.apache.geode.cache.EvictionAttributesMutator; import org.apache.geode.cache.ExpirationAttributes; import org.apache.geode.cache.Region; import org.apache.geode.cache.asyncqueue.AsyncEventQueue; import org.apache.geode.cache.wan.GatewaySender; import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; /** * The LookupRegionFactoryBean class is a concrete implementation of RegionLookupFactoryBean for handling * >gfe:lookup-region/< SDG XML namespace (XSD) elements. * * @author John Blum - * @see org.springframework.data.gemfire.RegionLookupFactoryBean + * @see RegionLookupFactoryBean * @see org.apache.geode.cache.AttributesMutator * @since 1.6.0 */ @SuppressWarnings("unused") public class LookupRegionFactoryBean extends RegionLookupFactoryBean { + private AsyncEventQueue[] asyncEventQueues; + private Boolean cloningEnabled; private Boolean enableStatistics; - private AsyncEventQueue[] asyncEventQueues; - private CacheListener[] cacheListeners; private CacheLoader cacheLoader; @@ -66,166 +68,123 @@ public class LookupRegionFactoryBean extends RegionLookupFactoryBean @Override public void afterPropertiesSet() throws Exception { + super.afterPropertiesSet(); - AttributesMutator attributesMutator = getRegion().getAttributesMutator(); + Optional.ofNullable(getRegion().getAttributesMutator()).ifPresent(attributesMutator -> { - if (!ObjectUtils.isEmpty(asyncEventQueues)) { - for (AsyncEventQueue asyncEventQueue : asyncEventQueues) { - attributesMutator.addAsyncEventQueueId(asyncEventQueue.getId()); - } - } + Arrays.stream(nullSafeArray(this.asyncEventQueues, AsyncEventQueue.class)) + .map(AsyncEventQueue::getId) + .forEach(attributesMutator::addAsyncEventQueueId); - if (!ObjectUtils.isEmpty(cacheListeners)) { - for (CacheListener cacheListener : cacheListeners) { - attributesMutator.addCacheListener(cacheListener); - } - } + Arrays.stream(nullSafeArray(this.cacheListeners, CacheListener.class)) + .forEach(attributesMutator::addCacheListener); - if (cacheLoader != null) { - attributesMutator.setCacheLoader(cacheLoader); - } + Optional.ofNullable(this.cacheLoader).ifPresent(attributesMutator::setCacheLoader); + Optional.ofNullable(this.cacheWriter).ifPresent(attributesMutator::setCacheWriter); + Optional.ofNullable(this.cloningEnabled).ifPresent(attributesMutator::setCloningEnabled); - if (cacheWriter != null) { - attributesMutator.setCacheWriter(cacheWriter); - } + // Eviction + Optional.ofNullable(attributesMutator.getEvictionAttributesMutator()) + .ifPresent(evictionAttributesMutator -> Optional.ofNullable(this.evictionMaximum) + .ifPresent(evictionAttributesMutator::setMaximum)); - if (cloningEnabled != null) { - attributesMutator.setCloningEnabled(cloningEnabled); - } + // Expiration + if (isStatisticsEnabled()) { - if (isStatisticsEnabled()) { - assertStatisticsEnabled(); + assertStatisticsEnabled(); - if (customEntryIdleTimeout != null) { - attributesMutator.setCustomEntryIdleTimeout(customEntryIdleTimeout); + Optional.ofNullable(this.customEntryIdleTimeout).ifPresent(attributesMutator::setCustomEntryIdleTimeout); + Optional.ofNullable(this.customEntryTimeToLive).ifPresent(attributesMutator::setCustomEntryTimeToLive); + Optional.ofNullable(this.entryIdleTimeout).ifPresent(attributesMutator::setEntryIdleTimeout); + Optional.ofNullable(this.entryTimeToLive).ifPresent(attributesMutator::setEntryTimeToLive); + Optional.ofNullable(this.regionIdleTimeout).ifPresent(attributesMutator::setRegionIdleTimeout); + Optional.ofNullable(this.regionTimeToLive).ifPresent(attributesMutator::setRegionTimeToLive); } - if (customEntryTimeToLive != null) { - attributesMutator.setCustomEntryTimeToLive(customEntryTimeToLive); - } - - if (entryIdleTimeout != null) { - attributesMutator.setEntryIdleTimeout(entryIdleTimeout); - } - - if (entryTimeToLive != null) { - attributesMutator.setEntryTimeToLive(entryTimeToLive); - } - - if (regionIdleTimeout != null) { - attributesMutator.setRegionIdleTimeout(regionIdleTimeout); - } - - if (regionTimeToLive != null) { - attributesMutator.setRegionTimeToLive(regionTimeToLive); - } - } - - if (evictionMaximum != null) { - EvictionAttributesMutator evictionAttributesMutator = attributesMutator.getEvictionAttributesMutator(); - evictionAttributesMutator.setMaximum(evictionMaximum); - } - - if (!ObjectUtils.isEmpty(gatewaySenders)) { - for (GatewaySender gatewaySender : gatewaySenders) { - attributesMutator.addGatewaySenderId(gatewaySender.getId()); - } - } + Arrays.stream(nullSafeArray(this.gatewaySenders, GatewaySender.class)) + .map(GatewaySender::getId) + .forEach(attributesMutator::addGatewaySenderId); + }); } @Override - final boolean isLookupEnabled() { + public final boolean isLookupEnabled() { return true; } - /* (non-Javadoc) */ public void setAsyncEventQueues(AsyncEventQueue[] asyncEventQueues) { this.asyncEventQueues = asyncEventQueues; } - /* (non-Javadoc) */ public void setCacheListeners(CacheListener[] cacheListeners) { this.cacheListeners = cacheListeners; } - /* (non-Javadoc) */ public void setCacheLoader(CacheLoader cacheLoader) { this.cacheLoader = cacheLoader; } - /* (non-Javadoc) */ public void setCacheWriter(CacheWriter cacheWriter) { this.cacheWriter = cacheWriter; } - /* (non-Javadoc) */ public void setCloningEnabled(Boolean cloningEnabled) { this.cloningEnabled = cloningEnabled; } - /* (non-Javadoc) */ public void setCustomEntryIdleTimeout(CustomExpiry customEntryIdleTimeout) { setStatisticsEnabled(customEntryIdleTimeout != null); this.customEntryIdleTimeout = customEntryIdleTimeout; } - /* (non-Javadoc) */ public void setCustomEntryTimeToLive(CustomExpiry customEntryTimeToLive) { setStatisticsEnabled(customEntryTimeToLive != null); this.customEntryTimeToLive = customEntryTimeToLive; } - /* (non-Javadoc) */ public void setEntryIdleTimeout(ExpirationAttributes entryIdleTimeout) { setStatisticsEnabled(entryIdleTimeout != null); this.entryIdleTimeout = entryIdleTimeout; } - /* (non-Javadoc) */ public void setEntryTimeToLive(ExpirationAttributes entryTimeToLive) { setStatisticsEnabled(entryTimeToLive != null); this.entryTimeToLive = entryTimeToLive; } - /* (non-Javadoc) */ public void setEvictionMaximum(final Integer evictionMaximum) { this.evictionMaximum = evictionMaximum; } - /* (non-Javadoc) */ public void setGatewaySenders(GatewaySender[] gatewaySenders) { this.gatewaySenders = gatewaySenders; } - /* (non-Javadoc) */ public void setRegionIdleTimeout(ExpirationAttributes regionIdleTimeout) { setStatisticsEnabled(regionIdleTimeout != null); this.regionIdleTimeout = regionIdleTimeout; } - /* (non-Javadoc) */ public void setRegionTimeToLive(ExpirationAttributes regionTimeToLive) { setStatisticsEnabled(regionTimeToLive != null); this.regionTimeToLive = regionTimeToLive; } - /* (non-Javadoc) */ public void setStatisticsEnabled(Boolean enableStatistics) { this.enableStatistics = enableStatistics; } - /* (non-Javadoc) */ protected boolean isStatisticsEnabled() { return Boolean.TRUE.equals(this.enableStatistics); } - /* (non-Javadoc) */ private void assertStatisticsEnabled() { + Region localRegion = getRegion(); - Assert.state(localRegion.getAttributes().getStatisticsEnabled(), String.format( - "Statistics for Region '%1$s' must be enabled to change Entry & Region TTL/TTI Expiration settings", + + Assert.state(localRegion.getAttributes().getStatisticsEnabled(), + String.format("Statistics for Region [%s] must be enabled to change Entry & Region TTL/TTI Expiration settings", localRegion.getFullPath())); } - } diff --git a/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java index 02bcdd29..858fc1a9 100644 --- a/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java @@ -17,6 +17,7 @@ package org.springframework.data.gemfire; import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.RegionFactory; +import org.springframework.data.gemfire.util.RegionUtils; import org.springframework.util.Assert; /** @@ -39,7 +40,7 @@ public class PartitionedRegionFactoryBean extends RegionFactoryBean } // Validate the data-policy and persistent attributes are compatible when specified! - assertDataPolicyAndPersistentAttributesAreCompatible(dataPolicy); + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(dataPolicy, persistent); regionFactory.setDataPolicy(dataPolicy); setDataPolicy(dataPolicy); diff --git a/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java index a7e1700f..72962e45 100644 --- a/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java @@ -18,19 +18,11 @@ package org.springframework.data.gemfire; import static java.util.Arrays.stream; import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; -import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeCollection; -import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeIterable; import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; import java.util.Optional; -import java.util.stream.StreamSupport; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.geode.cache.AttributesFactory; import org.apache.geode.cache.Cache; import org.apache.geode.cache.CacheListener; @@ -56,7 +48,7 @@ import org.springframework.beans.factory.FactoryBean; import org.springframework.context.SmartLifecycle; import org.springframework.core.io.Resource; import org.springframework.data.gemfire.client.ClientRegionFactoryBean; -import org.springframework.data.gemfire.config.annotation.RegionConfigurer; +import org.springframework.data.gemfire.util.RegionUtils; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; @@ -88,16 +80,15 @@ import org.springframework.util.StringUtils; * @see org.apache.geode.cache.asyncqueue.AsyncEventQueue * @see org.springframework.beans.factory.DisposableBean * @see org.springframework.context.SmartLifecycle - * @see org.springframework.data.gemfire.RegionLookupFactoryBean + * @see RegionLookupFactoryBean * @see org.springframework.data.gemfire.client.ClientRegionFactoryBean * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer */ @SuppressWarnings("unused") -public abstract class RegionFactoryBean extends RegionLookupFactoryBean +// TODO: Rename to PeerRegionFatoryBean in SD Lovelace +public abstract class RegionFactoryBean extends ConfigurableRegionFactoryBean implements DisposableBean, SmartLifecycle { - protected final Log log = LogFactory.getLog(getClass()); - private boolean close = true; private boolean destroy = false; private boolean running; @@ -124,19 +115,8 @@ public abstract class RegionFactoryBean extends RegionLookupFactoryBean regionConfigurers = Collections.emptyList(); - private RegionAttributes attributes; - private RegionConfigurer compositeRegionConfigurer = new RegionConfigurer() { - - @Override - public void configure(String beanName, RegionFactoryBean bean) { - nullSafeCollection(regionConfigurers) - .forEach(regionConfigurer -> regionConfigurer.configure(beanName, bean)); - } - }; - private RegionShortcut shortcut; private Resource snapshot; @@ -170,40 +150,6 @@ public abstract class RegionFactoryBean extends RegionLookupFactoryBean regionConfigurers) { - StreamSupport.stream(nullSafeIterable(regionConfigurers).spliterator(), false) - .forEach(regionConfigurer -> regionConfigurer.configure(regionName, this)); - } - - /* (non-Javadoc) */ private Region enableAsLockGrantor(Region region) { Optional.ofNullable(region) @@ -213,7 +159,6 @@ public abstract class RegionFactoryBean extends RegionLookupFactoryBean newRegion(RegionFactory regionFactory, Region parentRegion, String regionName) { return Optional.ofNullable(parentRegion) @@ -230,7 +175,6 @@ public abstract class RegionFactoryBean extends RegionLookupFactoryBean extends RegionLookupFactoryBean newIllegalArgumentException("Peer Cache is required")); } - /* (non-Javadoc) */ private RegionAttributes verifyLockGrantorEligibility(RegionAttributes regionAttributes, Scope scope) { Optional.ofNullable(regionAttributes).ifPresent(attributes -> @@ -249,9 +192,8 @@ public abstract class RegionFactoryBean extends RegionLookupFactoryBean extends RegionLookupFactoryBean regionFactory.addGatewaySenderId(((GatewaySender) gatewaySender).getId())); + .forEach(gatewaySender -> regionFactory.addGatewaySenderId(gatewaySender.getId())); Optional.ofNullable(this.keyConstraint).ifPresent(regionFactory::setKeyConstraint); @@ -343,23 +285,12 @@ public abstract class RegionFactoryBean extends RegionLookupFactoryBean extends RegionLookupFactoryBean RegionShortcutToDataPolicyConverter.INSTANCE.convert(regionShortcut)); } - /* (non-Javadoc) */ @SuppressWarnings("unchecked") private Optional getFieldValue(Object source, String fieldName, Class targetType) { @@ -470,27 +400,30 @@ public abstract class RegionFactoryBean extends RegionLookupFactoryBean extends RegionLookupFactoryBean extends RegionLookupFactoryBean extends RegionLookupFactoryBean extends RegionLookupFactoryBean regionFactory, Boolean persistent, DataPolicy dataPolicy) { if (dataPolicy != null) { - assertDataPolicyAndPersistentAttributesAreCompatible(dataPolicy); + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(dataPolicy, this.persistent); regionFactory.setDataPolicy(dataPolicy); setDataPolicy(dataPolicy); } @@ -635,8 +532,9 @@ public abstract class RegionFactoryBean extends RegionLookupFactoryBean extends RegionLookupFactoryBean extends RegionLookupFactoryBean regionConfigurers) { - this.regionConfigurers = Optional.ofNullable(regionConfigurers).orElseGet(Collections::emptyList); - } - public Scope getScope() { return this.scope; } @@ -941,9 +814,9 @@ public abstract class RegionFactoryBean extends RegionLookupFactoryBean extends RegionLookupFactoryBean extends AbstractFactoryBeanSupport> implements InitializingBean { @@ -74,15 +75,12 @@ public abstract class RegionLookupFactoryBean extends AbstractFactoryBeanS @SuppressWarnings("all") public void afterPropertiesSet() throws Exception { - GemFireCache cache = getCache(); + GemFireCache cache = requireCache(); - Assert.notNull(cache, "Cache is required"); - - String regionName = resolveRegionName(); - - Assert.hasText(regionName, "regionName, name or beanName property must be set"); + String regionName = requireRegionName(); synchronized (cache) { + setRegion(isLookupEnabled() ? Optional.ofNullable(getParent()) .map(parentRegion -> parentRegion.getSubregion(regionName)) @@ -101,6 +99,35 @@ public abstract class RegionLookupFactoryBean extends AbstractFactoryBeanS } } + private GemFireCache requireCache() { + + GemFireCache cache = getCache(); + + Assert.notNull(cache, "Cache is required"); + + return cache; + } + + private String requireRegionName() { + + String regionName = resolveRegionName(); + + Assert.hasText(regionName, "regionName, name or the beanName property must be set"); + + return regionName; + } + + /** + * Resolves the {@link String name} of the {@link Region}. + * + * @return a {@link String} containing the name of the {@link Region}. + * @see org.apache.geode.cache.Region#getName() + */ + public String resolveRegionName() { + return StringUtils.hasText(this.regionName) ? this.regionName + : (StringUtils.hasText(this.name) ? this.name : getBeanName()); + } + /** * Creates a new {@link Region} with the given {@link String name}. * @@ -134,8 +161,8 @@ public abstract class RegionLookupFactoryBean extends AbstractFactoryBeanS try { region.loadSnapshot(snapshot.getInputStream()); } - catch (Exception e) { - throw newRuntimeException(e, "Failed to load snapshot [%s]", snapshot); + catch (Exception cause) { + throw newRuntimeException(cause, "Failed to load snapshot [%s]", snapshot); } }); @@ -177,17 +204,6 @@ public abstract class RegionLookupFactoryBean extends AbstractFactoryBeanS return Optional.ofNullable(getRegion()).map(Region::getClass).orElse((Class) Region.class); } - /** - * Resolves the {@link String name} of the {@link Region}. - * - * @return a {@link String} containing the name of the {@link Region}. - * @see org.apache.geode.cache.Region#getName() - */ - public String resolveRegionName() { - return (StringUtils.hasText(this.regionName) ? this.regionName - : (StringUtils.hasText(this.name) ? this.name : getBeanName())); - } - /** * Returns a reference to the {@link GemFireCache} used to create the {@link Region}. * @@ -208,17 +224,14 @@ public abstract class RegionLookupFactoryBean extends AbstractFactoryBeanS this.cache = cache; } - /* (non-Javadoc) */ - boolean isLookupEnabled() { + public boolean isLookupEnabled() { return Boolean.TRUE.equals(getLookupEnabled()); } - /* (non-Javadoc) */ public void setLookupEnabled(Boolean lookupEnabled) { this.lookupEnabled = lookupEnabled; } - /* (non-Javadoc) */ public Boolean getLookupEnabled() { return this.lookupEnabled; } diff --git a/src/main/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBean.java index 79331d4e..6fb56c3d 100644 --- a/src/main/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBean.java @@ -17,6 +17,7 @@ package org.springframework.data.gemfire; import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.RegionFactory; +import org.springframework.data.gemfire.util.RegionUtils; import org.springframework.util.Assert; /** @@ -27,6 +28,7 @@ public class ReplicatedRegionFactoryBean extends RegionFactoryBean { @Override protected void resolveDataPolicy(RegionFactory regionFactory, Boolean persistent, DataPolicy dataPolicy) { + if (dataPolicy == null) { dataPolicy = (isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.REPLICATE); } @@ -41,7 +43,7 @@ public class ReplicatedRegionFactoryBean extends RegionFactoryBean { } // Validate that the data-policy and persistent attributes are compatible when both are specified! - assertDataPolicyAndPersistentAttributesAreCompatible(dataPolicy); + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(dataPolicy, persistent); regionFactory.setDataPolicy(dataPolicy); setDataPolicy(dataPolicy); @@ -49,6 +51,7 @@ public class ReplicatedRegionFactoryBean extends RegionFactoryBean { @Override protected void resolveDataPolicy(RegionFactory regionFactory, Boolean persistent, String dataPolicy) { + DataPolicy resolvedDataPolicy = null; if (dataPolicy != null) { @@ -58,5 +61,4 @@ public class ReplicatedRegionFactoryBean extends RegionFactoryBean { resolveDataPolicy(regionFactory, persistent, resolvedDataPolicy); } - } 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 ce96c984..6d3e5bcd 100644 --- a/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java @@ -25,7 +25,6 @@ import java.net.InetSocketAddress; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Properties; import java.util.concurrent.atomic.AtomicBoolean; @@ -37,9 +36,6 @@ import org.apache.geode.cache.client.ClientCacheFactory; import org.apache.geode.cache.client.Pool; import org.apache.geode.cache.client.PoolManager; import org.apache.geode.distributed.DistributedSystem; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ApplicationContextEvent; @@ -122,21 +118,14 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat clientCacheConfigurer.configure(beanName, bean)); /** - * Post processes this {@link ClientCacheFactoryBean} before cache initialization. + * Applies the composite {@link ClientCacheConfigurer ClientCacheConfigurers} + * to this {@link ClientCacheFactoryBean}. * - * This is also the point at which any configured {@link ClientCacheConfigurer} beans are called. - * - * @param gemfireProperties {@link Properties} used to configure Pivotal GemFire/Apache Geode. - * @see org.springframework.data.gemfire.config.annotation.ClientCacheConfigurer - * @see java.util.Properties + * @see #getCompositeClientCacheConfigurer() + * @see #applyClientCacheConfigurers(ClientCacheConfigurer...) */ @Override - protected void postProcessBeforeCacheInitialization(Properties gemfireProperties) { - applyClientCacheConfigurers(); - } - - /* (non-Javadoc) */ - private void applyClientCacheConfigurers() { + protected void applyCacheConfigurers() { applyClientCacheConfigurers(getCompositeClientCacheConfigurer()); } @@ -221,12 +210,12 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat /** * Constructs a new instance of {@link ClientCacheFactory} initialized with the given Pivotal GemFire/Apache Geode - * {@link Properties} used to create an instance of a {@link ClientCache}. + * {@link Properties} used to construct, configure and initialize an instance of a {@link ClientCache}. * * @param gemfireProperties {@link Properties} used by the {@link ClientCacheFactory} * to configure the {@link ClientCache}. - * @return a new instance of {@link ClientCacheFactory} initialized with the given Pivotal GemFire/Apache Geode - * {@link Properties}. + * @return a new instance of {@link ClientCacheFactory} initialized with + * the given Pivotal GemFire/Apache Geode {@link Properties}. * @see org.apache.geode.cache.client.ClientCacheFactory * @see java.util.Properties */ @@ -236,17 +225,19 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat } /** - * Prepares and initializes the {@link ClientCacheFactory} used to create the {@link ClientCache}. + * Configures the {@link ClientCacheFactory} used to create the {@link ClientCache}. * * Sets PDX options specified by the user. * + * Sets Pool options specified by the user. + * * @param factory {@link ClientCacheFactory} used to create the {@link ClientCache}. - * @return the prepared and initialized {@link ClientCacheFactory}. - * @see #initializePdx(ClientCacheFactory) + * @return the configured {@link ClientCacheFactory}. + * @see #configurePdx(ClientCacheFactory) */ @Override - protected Object prepareFactory(Object factory) { - return initializePool(initializePdx((ClientCacheFactory) factory)); + protected Object configureFactory(Object factory) { + return configurePool(configurePdx((ClientCacheFactory) factory)); } /** @@ -256,7 +247,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat * @return the given {@link ClientCacheFactory} * @see org.apache.geode.cache.client.ClientCacheFactory */ - ClientCacheFactory initializePdx(ClientCacheFactory clientCacheFactory) { + ClientCacheFactory configurePdx(ClientCacheFactory clientCacheFactory) { Optional.ofNullable(getPdxSerializer()).ifPresent(clientCacheFactory::setPdxSerializer); @@ -280,10 +271,10 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat * @see org.apache.geode.cache.client.ClientCacheFactory * @see org.apache.geode.cache.client.Pool */ - ClientCacheFactory initializePool(ClientCacheFactory clientCacheFactory) { + ClientCacheFactory configurePool(ClientCacheFactory clientCacheFactory) { - DefaultableDelegatingPoolAdapter pool = DefaultableDelegatingPoolAdapter.from( - DelegatingPoolAdapter.from(resolvePool())).preferDefault(); + DefaultableDelegatingPoolAdapter pool = + DefaultableDelegatingPoolAdapter.from(DelegatingPoolAdapter.from(resolvePool())).preferDefault(); clientCacheFactory.setPoolFreeConnectionTimeout(pool.getFreeConnectionTimeout(getFreeConnectionTimeout())); clientCacheFactory.setPoolIdleTimeout(pool.getIdleTimeout(getIdleTimeout())); @@ -291,8 +282,8 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat clientCacheFactory.setPoolMaxConnections(pool.getMaxConnections(getMaxConnections())); clientCacheFactory.setPoolMinConnections(pool.getMinConnections(getMinConnections())); clientCacheFactory.setPoolMultiuserAuthentication(pool.getMultiuserAuthentication(getMultiUserAuthentication())); - clientCacheFactory.setPoolPRSingleHopEnabled(pool.getPRSingleHopEnabled(getPrSingleHopEnabled())); clientCacheFactory.setPoolPingInterval(pool.getPingInterval(getPingInterval())); + clientCacheFactory.setPoolPRSingleHopEnabled(pool.getPRSingleHopEnabled(getPrSingleHopEnabled())); clientCacheFactory.setPoolReadTimeout(pool.getReadTimeout(getReadTimeout())); clientCacheFactory.setPoolRetryAttempts(pool.getRetryAttempts(getRetryAttempts())); clientCacheFactory.setPoolServerGroup(pool.getServerGroup(getServerGroup())); @@ -305,13 +296,14 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat clientCacheFactory.setPoolSubscriptionRedundancy(pool.getSubscriptionRedundancy(getSubscriptionRedundancy())); clientCacheFactory.setPoolThreadLocalConnections(pool.getThreadLocalConnections(getThreadLocalConnections())); - final AtomicBoolean noServers = new AtomicBoolean(getServers().isEmpty()); + AtomicBoolean noServers = new AtomicBoolean(getServers().isEmpty()); - boolean hasServers = !noServers.get(); boolean noLocators = getLocators().isEmpty(); boolean hasLocators = !noLocators; + boolean hasServers = !noServers.get(); if (hasServers || noLocators) { + Iterable servers = pool.getServers(getServers().toInetSocketAddresses()); stream(servers.spliterator(), false).forEach(server -> { @@ -321,6 +313,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat } if (hasLocators || noServers.get()) { + Iterable locators = pool.getLocators(getLocators().toInetSocketAddresses()); stream(locators.spliterator(), false).forEach(locator -> @@ -331,63 +324,58 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat } /** - * Resolves an appropriate {@link Pool} from the Spring container that will be used to configure - * the {@link ClientCache}. + * Resolves the {@link Pool} used to configure the {@link ClientCache}, {@literal DEFAULT} {@link Pool}. * - * @return the resolved {@link Pool}. + * @return the resolved {@link Pool} used to configure the {@link ClientCache}, {@literal DEFAULT} {@link Pool}. + * @see org.apache.geode.cache.client.PoolManager#find(String) * @see org.apache.geode.cache.client.Pool + * @see #getPoolName() + * @see #getPool() * @see #findPool(String) + * @see #isPoolNameResolvable(String) */ Pool resolvePool() { - Pool localPool = getPool(); + Pool pool = getPool(); - if (localPool == null) { + if (pool == null) { - String poolName = Optional.ofNullable(getPoolName()).filter(StringUtils::hasText) - .orElse(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME); + String poolName = resolvePoolName(); - localPool = findPool(poolName); + pool = findPool(poolName); - if (localPool == null) { + if (pool == null && isPoolNameResolvable(poolName)) { - BeanFactory beanFactory = getBeanFactory(); + String dereferencedPoolName = SpringUtils.dereferenceBean(poolName); - if (beanFactory instanceof ListableBeanFactory) { - try { - Map poolFactoryBeanMap = - ((ListableBeanFactory) beanFactory).getBeansOfType(PoolFactoryBean.class, false, false); + PoolFactoryBean poolFactoryBean = + getBeanFactory().getBean(dereferencedPoolName, PoolFactoryBean.class); - String dereferencedPoolName = SpringUtils.dereferenceBean(poolName); - - if (poolFactoryBeanMap.containsKey(dereferencedPoolName)) { - return poolFactoryBeanMap.get(dereferencedPoolName).getPool(); - } - } - catch (BeansException e) { - logInfo("Unable to resolve bean of type [%1$s] with name [%2$s]", - PoolFactoryBean.class.getName(), poolName); - } - } + return poolFactoryBean.getPool(); } } - return localPool; + return pool; + } + + String resolvePoolName() { + + return Optional.ofNullable(getPoolName()) + .filter(StringUtils::hasText) + .orElse(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME); } - /** - * Attempts to find a {@link Pool} with the given {@link String name}. - * - * @param name {@link String} containing the name of the {@link Pool} to find. - * @return a {@link Pool} instance with the given {@link String name} registered in GemFire/Geode - * or {@literal null} if no {@link Pool} with the given {@link String name} exists. - * @see org.apache.geode.cache.client.PoolManager#find(String) - * @see org.apache.geode.cache.client.Pool - */ Pool findPool(String name) { return PoolManager.find(name); } + private boolean isPoolNameResolvable(String poolName) { + + return Optional.ofNullable(poolName) + .filter(getBeanFactory()::containsBean) + .isPresent(); + } + /** * Creates a new {@link ClientCache} instance using the provided factory. * @@ -420,7 +408,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat this.fetchCache().readyForEvents(); } catch (IllegalStateException | CacheClosedException ignore) { - // thrown if clientCache.readyForEvents() is called on a non-durable client + // Thrown when clientCache.readyForEvents() is called on a non-durable client } } } @@ -449,22 +437,18 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat return Optional.ofNullable(getCache()).map(Object::getClass).orElse((Class) ClientCache.class); } - /* (non-Javadoc) */ public void addLocators(ConnectionEndpoint... locators) { this.locators.add(locators); } - /* (non-Javadoc) */ public void addLocators(Iterable locators) { this.locators.add(locators); } - /* (non-Javadoc) */ public void addServers(ConnectionEndpoint... servers) { this.servers.add(servers); } - /* (non-Javadoc) */ public void addServers(Iterable servers) { this.servers.add(servers); } @@ -546,36 +530,30 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat return this.durableClientTimeout; } - /* (non-Javadoc) */ @Override public final void setEnableAutoReconnect(Boolean enableAutoReconnect) { throw new UnsupportedOperationException("Auto-reconnect does not apply to clients"); } - /* (non-Javadoc) */ @Override public final Boolean getEnableAutoReconnect() { return Boolean.FALSE; } - /* (non-Javadoc) */ public void setFreeConnectionTimeout(Integer freeConnectionTimeout) { this.freeConnectionTimeout = freeConnectionTimeout; } - /* (non-Javadoc) */ public Integer getFreeConnectionTimeout() { - return freeConnectionTimeout; + return this.freeConnectionTimeout; } - /* (non-Javadoc) */ public void setIdleTimeout(Long idleTimeout) { this.idleTimeout = idleTimeout; } - /* (non-Javadoc) */ public Long getIdleTimeout() { - return idleTimeout; + return this.idleTimeout; } /** @@ -595,7 +573,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat * @return a boolean value indicating whether the server should keep the durable client's queues alive. */ public Boolean getKeepAlive() { - return keepAlive; + return this.keepAlive; } /** @@ -608,60 +586,49 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat return Boolean.TRUE.equals(getKeepAlive()); } - /* (non-Javadoc) */ public void setLoadConditioningInterval(Integer loadConditioningInterval) { this.loadConditioningInterval = loadConditioningInterval; } - /* (non-Javadoc) */ public Integer getLoadConditioningInterval() { - return loadConditioningInterval; + return this.loadConditioningInterval; } - /* (non-Javadoc) */ public void setLocators(ConnectionEndpoint[] locators) { setLocators(ConnectionEndpointList.from(locators)); } - /* (non-Javadoc) */ public void setLocators(Iterable locators) { getLocators().clear(); addLocators(locators); } - /* (non-Javadoc) */ protected ConnectionEndpointList getLocators() { - return locators; + return this.locators; } - /* (non-Javadoc) */ public void setMaxConnections(Integer maxConnections) { this.maxConnections = maxConnections; } - /* (non-Javadoc) */ public Integer getMaxConnections() { - return maxConnections; + return this.maxConnections; } - /* (non-Javadoc) */ public void setMinConnections(Integer minConnections) { this.minConnections = minConnections; } - /* (non-Javadoc) */ public Integer getMinConnections() { - return minConnections; + return this.minConnections; } - /* (non-Javadoc) */ public void setMultiUserAuthentication(Boolean multiUserAuthentication) { this.multiUserAuthentication = multiUserAuthentication; } - /* (non-Javadoc) */ public Boolean getMultiUserAuthentication() { - return multiUserAuthentication; + return this.multiUserAuthentication; } /** @@ -701,37 +668,31 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat * @return the name of the GemFire {@link Pool} used by this GemFire cache client. */ public String getPoolName() { - return poolName; + return this.poolName; } - /* (non-Javadoc) */ public void setPingInterval(Long pingInterval) { this.pingInterval = pingInterval; } - /* (non-Javadoc) */ public Long getPingInterval() { - return pingInterval; + return this.pingInterval; } - /* (non-Javadoc) */ public void setPrSingleHopEnabled(Boolean prSingleHopEnabled) { this.prSingleHopEnabled = prSingleHopEnabled; } - /* (non-Javadoc) */ public Boolean getPrSingleHopEnabled() { - return prSingleHopEnabled; + return this.prSingleHopEnabled; } - /* (non-Javadoc) */ public void setReadTimeout(Integer readTimeout) { this.readTimeout = readTimeout; } - /* (non-Javadoc) */ public Integer getReadTimeout() { - return readTimeout; + return this.readTimeout; } /** @@ -752,7 +713,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat * @return a boolean value indicating the state of the 'readyForEvents' property. */ public Boolean getReadyForEvents(){ - return readyForEvents; + return this.readyForEvents; } /** @@ -780,129 +741,104 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat } } - /* (non-Javadoc) */ public void setRetryAttempts(Integer retryAttempts) { this.retryAttempts = retryAttempts; } - /* (non-Javadoc) */ public Integer getRetryAttempts() { - return retryAttempts; + return this.retryAttempts; } - /* (non-Javadoc) */ public void setServerGroup(String serverGroup) { this.serverGroup = serverGroup; } - /* (non-Javadoc) */ public String getServerGroup() { - return serverGroup; + return this.serverGroup; } - /* (non-Javadoc) */ public void setServers(ConnectionEndpoint[] servers) { setServers(ConnectionEndpointList.from(servers)); } - /* (non-Javadoc) */ public void setServers(Iterable servers) { getServers().clear(); addServers(servers); } - /* (non-Javadoc) */ protected ConnectionEndpointList getServers() { - return servers; + return this.servers; } - /* (non-Javadoc) */ public void setSocketBufferSize(Integer socketBufferSize) { this.socketBufferSize = socketBufferSize; } - /* (non-Javadoc) */ public Integer getSocketBufferSize() { - return socketBufferSize; + return this.socketBufferSize; } - /* (non-Javadoc) */ public void setSocketConnectTimeout(Integer socketConnectTimeout) { this.socketConnectTimeout = socketConnectTimeout; } - /* (non-Javadoc) */ public Integer getSocketConnectTimeout() { return this.socketConnectTimeout; } - /* (non-Javadoc) */ public void setStatisticsInterval(Integer statisticsInterval) { this.statisticsInterval = statisticsInterval; } - /* (non-Javadoc) */ public Integer getStatisticsInterval() { - return statisticsInterval; + return this.statisticsInterval; } - /* (non-Javadoc) */ public void setSubscriptionAckInterval(Integer subscriptionAckInterval) { this.subscriptionAckInterval = subscriptionAckInterval; } - /* (non-Javadoc) */ public Integer getSubscriptionAckInterval() { - return subscriptionAckInterval; + return this.subscriptionAckInterval; } - /* (non-Javadoc) */ public void setSubscriptionEnabled(Boolean subscriptionEnabled) { this.subscriptionEnabled = subscriptionEnabled; } - /* (non-Javadoc) */ public Boolean getSubscriptionEnabled() { - return subscriptionEnabled; + return this.subscriptionEnabled; } - /* (non-Javadoc) */ public void setSubscriptionMessageTrackingTimeout(Integer subscriptionMessageTrackingTimeout) { this.subscriptionMessageTrackingTimeout = subscriptionMessageTrackingTimeout; } - /* (non-Javadoc) */ public Integer getSubscriptionMessageTrackingTimeout() { - return subscriptionMessageTrackingTimeout; + return this.subscriptionMessageTrackingTimeout; } - /* (non-Javadoc) */ public void setSubscriptionRedundancy(Integer subscriptionRedundancy) { this.subscriptionRedundancy = subscriptionRedundancy; } - /* (non-Javadoc) */ public Integer getSubscriptionRedundancy() { - return subscriptionRedundancy; + return this.subscriptionRedundancy; } - /* (non-Javadoc) */ public void setThreadLocalConnections(Boolean threadLocalConnections) { this.threadLocalConnections = threadLocalConnections; } - /* (non-Javadoc) */ public Boolean getThreadLocalConnections() { - return threadLocalConnections; + return this.threadLocalConnections; } - /* (non-Javadoc) */ @Override public final void setUseClusterConfiguration(Boolean useClusterConfiguration) { throw new UnsupportedOperationException("Cluster-based Configuration is not applicable for clients"); } - /* (non-Javadoc) */ @Override public final Boolean getUseClusterConfiguration() { return Boolean.FALSE; 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 361e98f0..27e7d5a6 100644 --- a/src/main/java/org/springframework/data/gemfire/client/ClientRegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/ClientRegionFactoryBean.java @@ -19,20 +19,20 @@ package org.springframework.data.gemfire.client; import static java.util.Arrays.stream; import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeCollection; -import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeIterable; import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.stream.StreamSupport; +import java.util.concurrent.atomic.AtomicReference; import org.apache.geode.cache.CacheListener; import org.apache.geode.cache.CacheLoader; import org.apache.geode.cache.CacheWriter; +import org.apache.geode.cache.CustomExpiry; import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.EvictionAttributes; +import org.apache.geode.cache.ExpirationAttributes; import org.apache.geode.cache.GemFireCache; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionAttributes; @@ -42,14 +42,16 @@ import org.apache.geode.cache.client.ClientRegionShortcut; import org.apache.geode.cache.client.Pool; import org.apache.geode.cache.client.PoolManager; import org.apache.geode.compression.Compressor; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; +import org.springframework.data.gemfire.ConfigurableRegionFactoryBean; import org.springframework.data.gemfire.DataPolicyConverter; import org.springframework.data.gemfire.GemfireUtils; import org.springframework.data.gemfire.RegionLookupFactoryBean; import org.springframework.data.gemfire.config.annotation.RegionConfigurer; import org.springframework.data.gemfire.config.xml.GemfireConstants; +import org.springframework.data.gemfire.util.RegionUtils; +import org.springframework.data.gemfire.util.SpringUtils; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -71,11 +73,11 @@ import org.springframework.util.StringUtils; * @see org.springframework.beans.factory.DisposableBean * @see org.springframework.beans.factory.FactoryBean * @see org.springframework.data.gemfire.DataPolicyConverter - * @see org.springframework.data.gemfire.RegionLookupFactoryBean + * @see RegionLookupFactoryBean * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer */ @SuppressWarnings("unused") -public class ClientRegionFactoryBean extends RegionLookupFactoryBean implements DisposableBean { +public class ClientRegionFactoryBean extends ConfigurableRegionFactoryBean implements DisposableBean { public static final String DEFAULT_POOL_NAME = "DEFAULT"; public static final String GEMFIRE_POOL_NAME = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME; @@ -83,7 +85,11 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean private boolean close = false; private boolean destroy = false; + private Boolean cloningEnabled; + private Boolean concurrencyChecksEnabled; + private Boolean diskSynchronous; private Boolean persistent; + private Boolean statisticsEnabled; private CacheListener[] cacheListeners; @@ -98,12 +104,25 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean private Compressor compressor; + private CustomExpiry customEntryIdleTimeout; + private CustomExpiry customEntryTimeToLive; + private DataPolicy dataPolicy; private EvictionAttributes evictionAttributes; + private ExpirationAttributes entryIdleTimeout; + private ExpirationAttributes entryTimeToLive; + private ExpirationAttributes regionIdleTimeout; + private ExpirationAttributes regionTimeToLive; + + private Integer concurrencyLevel; + private Integer initialCapacity; + private Interest[] interests; + private Float loadFactor; + private List regionConfigurers = Collections.emptyList(); private RegionAttributes attributes; @@ -126,6 +145,8 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean * @param gemfireCache reference to the {@link GemFireCache}. * @param regionName {@link String name} of the new {@link Region}. * @return a new {@link Region} with the given {@link String name}. + * @see #createClientRegionFactory(ClientCache, ClientRegionShortcut) + * @see #newRegion(ClientRegionFactory, Region, String) * @see org.apache.geode.cache.GemFireCache * @see org.apache.geode.cache.Region */ @@ -139,109 +160,37 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean ClientRegionFactory clientRegionFactory = postProcess(configure(createClientRegionFactory(clientCache, resolveClientRegionShortcut()))); - @SuppressWarnings("all") - Region region = newRegion(clientRegionFactory, getParent(), regionName); - - return region; - } - - /* (non-Javadoc) */ - private void applyRegionConfigurers(String regionName) { - applyRegionConfigurers(regionName, getCompositeRegionConfigurer()); + return newRegion(clientRegionFactory, getParent(), regionName); } /** - * Null-safe operation to apply the given array of {@link RegionConfigurer RegionConfigurers} - * to this {@link ClientRegionFactoryBean}. + * Constructs a new {@link Region} using the provided {@link ClientRegionFactory} as either + * a {@link Region root Region} or a {@link Region sub-Region} if {@link Region parent} + * is not {@literal null}. * - * @param regionName {@link String} containing the name of the {@link Region}. - * @param regionConfigurers array of {@link RegionConfigurer RegionConfigurers} applied - * to this {@link ClientRegionFactoryBean}. - * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer - * @see #applyRegionConfigurers(String, Iterable) + * @param clientRegionFactory {@link ClientRegionFactory} containing the configuration + * for the new {@link Region}. + * @param parent {@link Region} designated as the parent of the new {@link Region} + * if the new {@link Region} is a {@link Region sub-Region}. + * @param regionName {@link String name} of the new {@link Region}. + * @return the new {@link Region} initialized with the given {@link String name}. */ - protected void applyRegionConfigurers(String regionName, RegionConfigurer... regionConfigurers) { - applyRegionConfigurers(regionName, Arrays.asList(nullSafeArray(regionConfigurers, RegionConfigurer.class))); - } - - /** - * Null-safe operation to apply the given {@link Iterable} of {@link RegionConfigurer RegionConfigurers} - * to this {@link ClientRegionFactoryBean}. - * - * @param regionName {@link String} containing the name of the {@link Region}. - * @param regionConfigurers {@link Iterable} of {@link RegionConfigurer RegionConfigurers} applied - * to this {@link ClientRegionFactoryBean}. - * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer - */ - protected void applyRegionConfigurers(String regionName, Iterable regionConfigurers) { - StreamSupport.stream(nullSafeIterable(regionConfigurers).spliterator(), false) - .forEach(regionConfigurer -> regionConfigurer.configure(regionName, this)); - } - - /** - * Assert the settings for {@link ClientRegionShortcut} and the {@literal persistent} attribute - * in <gfe:*-region> elements are compatible. - * - * @param resolvedShortcut {@link ClientRegionShortcut} resolved from the SDG XML namespace. - * @see org.springframework.data.gemfire.client.ClientRegionShortcutWrapper - * @see org.apache.geode.cache.client.ClientRegionShortcut - * @see #isNotPersistent() - * @see #isPersistent() - */ - private void assertClientRegionShortcutAndPersistentAttributeAreCompatible(ClientRegionShortcut resolvedShortcut) { - - final boolean persistentNotSpecified = (this.persistent == null); - - if (ClientRegionShortcutWrapper.valueOf(resolvedShortcut).isPersistent()) { - Assert.isTrue(persistentNotSpecified || isPersistent(), - String.format("Client Region Shortcut [%s] is not valid when persistent is false", resolvedShortcut)); - } - else { - Assert.isTrue(persistentNotSpecified || isNotPersistent(), - String.format("Client Region Shortcut [%s] is not valid when persistent is true", resolvedShortcut)); - } - } - - /** - * Assert the settings for {@link DataPolicy} and the persistent attribute - * in <gfe:*-region> elements are compatible. - * - * @param resolvedDataPolicy {@link DataPolicy} resolved from the SDG XML namespace. - * @see org.apache.geode.cache.DataPolicy - * @see #isNotPersistent() - * @see #isPersistent() - */ - private void assertDataPolicyAndPersistentAttributeAreCompatible(DataPolicy resolvedDataPolicy) { - - if (resolvedDataPolicy.withPersistence()) { - Assert.isTrue(isPersistentUnspecified() || isPersistent(), - String.format("Data Policy [%s] is not valid when persistent is false", resolvedDataPolicy)); - } - else { - Assert.isTrue(isPersistentUnspecified() || isNotPersistent(), - String.format("Data Policy [%s] is not valid when persistent is true", resolvedDataPolicy)); - } - } - - /* (non-Javadoc) */ private Region newRegion(ClientRegionFactory clientRegionFactory, - Region parentRegion, String regionName) { + Region parent, String regionName) { - return Optional.ofNullable(parentRegion) - .map(parent -> { - logInfo("Creating client Subregion [%1$s] with parent Region [%2$s]", - regionName, parent.getName()); + if (parent != null) { - return clientRegionFactory.createSubregion(parent, regionName); - }) - .orElseGet(() -> { - logInfo("Created client Region [%s]", regionName); + logInfo("Creating client sub-Region [%1$s] with parent Region [%2$s]", + regionName, parent.getName()); - return clientRegionFactory.create(regionName); - }); + return clientRegionFactory.createSubregion(parent, regionName); + } + else { + logInfo("Creating client Region [%s]", regionName); + return clientRegionFactory.create(regionName); + } } - /* (non-Javadoc) */ private ClientCache resolveCache(GemFireCache gemfireCache) { return Optional.ofNullable(gemfireCache) @@ -251,9 +200,11 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean } /** - * Resolves the {@link ClientRegionShortcut} used to configure the {@link DataPolicy} of the client {@link Region}. + * Resolves the {@link ClientRegionShortcut} used to configure the {@link DataPolicy} + * for the {@link Region client Region}. * - * @return a {@link ClientRegionShortcut} used to configure the {@link DataPolicy} of the client {@link Region}. + * @return a {@link ClientRegionShortcut} used to configure the {@link DataPolicy} + * for the {@link Region client Region}. * @see org.apache.geode.cache.client.ClientRegionShortcut * @see org.apache.geode.cache.DataPolicy */ @@ -267,7 +218,7 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean if (dataPolicy != null) { - assertDataPolicyAndPersistentAttributeAreCompatible(dataPolicy); + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(dataPolicy, this.persistent); if (DataPolicy.EMPTY.equals(dataPolicy)) { resolvedShortcut = ClientRegionShortcut.PROXY; @@ -279,57 +230,48 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean resolvedShortcut = ClientRegionShortcut.LOCAL_PERSISTENT; } else { - // NOTE the DataPolicy validation is based on the ClientRegionShortcut initialization logic - // in org.apache.geode.internal.cache.GemFireCacheImpl.initializeClientRegionShortcuts + // NOTE: DataPolicy validation is based on the ClientRegionShortcut initialization logic + // in org.apache.geode.internal.cache.GemFireCacheImpl.initializeClientRegionShortcuts. throw newIllegalArgumentException("Data Policy [%s] is not valid for a client Region", dataPolicy); } } else { - resolvedShortcut = (isPersistent() ? ClientRegionShortcut.LOCAL_PERSISTENT : ClientRegionShortcut.LOCAL); + resolvedShortcut = isPersistent() ? ClientRegionShortcut.LOCAL_PERSISTENT : ClientRegionShortcut.LOCAL; } } - // NOTE the ClientRegionShortcut and Persistent attribute will be compatible - // if the shortcut was derived from the Data Policy. - assertClientRegionShortcutAndPersistentAttributeAreCompatible(resolvedShortcut); + // NOTE: The ClientRegionShortcut and Persistent attribute will be compatible + // if the shortcut was derived from the DataPolicy. + RegionUtils.assertClientRegionShortcutAndPersistentAttributeAreCompatible(resolvedShortcut, this.persistent); return resolvedShortcut; } - /* (non-Javadoc) */ - private String resolvePoolName() { + private String resolvePoolName(String factoryPoolName, String attributesPoolName) { - return getPoolName() + String resolvedPoolName = StringUtils.hasText(factoryPoolName) ? factoryPoolName : attributesPoolName; + + return Optional.ofNullable(resolvedPoolName) .filter(StringUtils::hasText) - .filter(this::isNotDefaultPool) - .filter(this::isPoolResolvable) + .filter(GemfireUtils::isNotDefaultPool) + .map(it -> { + + Assert.isTrue(eagerlyInitializePool(it), + String.format("[%s] is not resolvable as a Pool in the application context", it)); + + return it; + }) .orElse(null); } - /* (non-Javadoc) */ - boolean isPoolResolvable(String poolName) { - return getBeanFactory().containsBean(poolName) || (PoolManager.find(poolName) != null); - } + @SuppressWarnings("all") + private boolean eagerlyInitializePool(String poolName) { - /* (non-Javadoc) */ - boolean isNotDefaultPool(String poolName) { - return !DEFAULT_POOL_NAME.equals(poolName); - } - - /* (non-Javadoc) */ - private String eagerlyInitializePool(String poolName) { - - try { - if (getBeanFactory().isTypeMatch(poolName, Pool.class)) { - logDebug("Found bean definition for Pool [%s]; Eagerly initializing...", poolName); - getBeanFactory().getBean(poolName, Pool.class); - } - } - catch (BeansException ignore) { - getLog().warn(ignore.getMessage(), ignore.getCause()); - } - - return poolName; + return Optional.ofNullable(PoolManager.find(poolName)) + .map(it -> true) + .orElseGet(() -> + SpringUtils.safeGetValue(() -> + getBeanFactory().getBean(poolName, Pool.class) != null, false)); } /** @@ -337,81 +279,93 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean * and {@link ClientRegionShortcut}. * * @param clientCache reference to the {@link ClientCache}. - * @param shortcut {@link ClientRegionShortcut} used to specify the client {@link Region} {@link DataPolicy}. + * @param clientRegionShortcut {@link ClientRegionShortcut} used to configure + * the {@link Region client Region} {@link DataPolicy}. * @return a new instance of {@link ClientRegionFactory}. * @see org.apache.geode.cache.client.ClientCache#createClientRegionFactory(ClientRegionShortcut) * @see org.apache.geode.cache.client.ClientRegionShortcut * @see org.apache.geode.cache.client.ClientRegionFactory */ protected ClientRegionFactory createClientRegionFactory(ClientCache clientCache, - ClientRegionShortcut shortcut) { + ClientRegionShortcut clientRegionShortcut) { - return clientCache.createClientRegionFactory(shortcut); + return clientCache.createClientRegionFactory(clientRegionShortcut); } /** * Configures the given {@link ClientRegionFactoryBean} from the configuration settings - * of this {@link ClientRegionFactoryBean}. + * of this {@link ClientRegionFactoryBean} and any {@link RegionAttributes}. * * @param clientRegionFactory {@link ClientRegionFactory} to configure. - * @return the given {@link ClientRegionFactory}. + * @return the configured {@link ClientRegionFactory}. * @see org.apache.geode.cache.client.ClientRegionFactory */ protected ClientRegionFactory configure(ClientRegionFactory clientRegionFactory) { - Optional.ofNullable(this.attributes).ifPresent(attributes -> { - - stream(nullSafeArray(attributes.getCacheListeners(), CacheListener.class)) - .forEach(clientRegionFactory::addCacheListener); - - 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.setRegionIdleTimeout(attributes.getRegionIdleTimeout()); - clientRegionFactory.setRegionTimeToLive(attributes.getRegionTimeToLive()); - clientRegionFactory.setStatisticsEnabled(attributes.getStatisticsEnabled()); - clientRegionFactory.setValueConstraint(attributes.getValueConstraint()); - - Optional.ofNullable(attributes.getPoolName()) - .filter(StringUtils::hasText) - .filter(this::isNotDefaultPool) - .filter(this::isPoolResolvable) - .map(this::eagerlyInitializePool) - .ifPresent(clientRegionFactory::setPoolName); - - }); + Optional regionAttributesPoolName = configureWithRegionAttributes(clientRegionFactory); stream(nullSafeArray(this.cacheListeners, CacheListener.class)).forEach(clientRegionFactory::addCacheListener); + Optional.ofNullable(this.cloningEnabled).ifPresent(clientRegionFactory::setCloningEnabled); Optional.ofNullable(this.compressor).ifPresent(clientRegionFactory::setCompressor); - - Optional.ofNullable(this.diskStoreName).filter(StringUtils::hasText) - .ifPresent(clientRegionFactory::setDiskStoreName); - + Optional.ofNullable(this.concurrencyChecksEnabled).ifPresent(clientRegionFactory::setConcurrencyChecksEnabled); + Optional.ofNullable(this.concurrencyLevel).ifPresent(clientRegionFactory::setConcurrencyLevel); + Optional.ofNullable(this.customEntryIdleTimeout).ifPresent(clientRegionFactory::setCustomEntryIdleTimeout); + Optional.ofNullable(this.customEntryTimeToLive).ifPresent(clientRegionFactory::setCustomEntryTimeToLive); + Optional.ofNullable(this.diskStoreName).filter(StringUtils::hasText).ifPresent(clientRegionFactory::setDiskStoreName); + Optional.ofNullable(this.diskSynchronous).ifPresent(clientRegionFactory::setDiskSynchronous); + Optional.ofNullable(this.entryIdleTimeout).ifPresent(clientRegionFactory::setEntryIdleTimeout); + Optional.ofNullable(this.entryTimeToLive).ifPresent(clientRegionFactory::setEntryTimeToLive); Optional.ofNullable(this.evictionAttributes).ifPresent(clientRegionFactory::setEvictionAttributes); - + Optional.ofNullable(this.initialCapacity).ifPresent(clientRegionFactory::setInitialCapacity); Optional.ofNullable(this.keyConstraint).ifPresent(clientRegionFactory::setKeyConstraint); + Optional.ofNullable(this.loadFactor).ifPresent(clientRegionFactory::setLoadFactor); - Optional.ofNullable(resolvePoolName()) - .map(this::eagerlyInitializePool) + Optional.ofNullable(resolvePoolName(getPoolName().orElse(null), regionAttributesPoolName.orElse(null))) .ifPresent(clientRegionFactory::setPoolName); + Optional.ofNullable(this.regionIdleTimeout).ifPresent(clientRegionFactory::setRegionIdleTimeout); + Optional.ofNullable(this.regionTimeToLive).ifPresent(clientRegionFactory::setRegionTimeToLive); + Optional.ofNullable(this.statisticsEnabled).ifPresent(clientRegionFactory::setStatisticsEnabled); Optional.ofNullable(this.valueConstraint).ifPresent(clientRegionFactory::setValueConstraint); return clientRegionFactory; } + private Optional configureWithRegionAttributes(ClientRegionFactory clientRegionFactory) { + + AtomicReference regionAttributesPoolName = new AtomicReference<>(null); + + Optional.ofNullable(getAttributes()).ifPresent(regionAttributes -> { + + regionAttributesPoolName.set(regionAttributes.getPoolName()); + + stream(nullSafeArray(regionAttributes.getCacheListeners(), CacheListener.class)) + .forEach(clientRegionFactory::addCacheListener); + + clientRegionFactory.setCloningEnabled(regionAttributes.getCloningEnabled()); + clientRegionFactory.setCompressor(regionAttributes.getCompressor()); + clientRegionFactory.setConcurrencyChecksEnabled(regionAttributes.getConcurrencyChecksEnabled()); + clientRegionFactory.setConcurrencyLevel(regionAttributes.getConcurrencyLevel()); + clientRegionFactory.setCustomEntryIdleTimeout(regionAttributes.getCustomEntryIdleTimeout()); + clientRegionFactory.setCustomEntryTimeToLive(regionAttributes.getCustomEntryTimeToLive()); + clientRegionFactory.setDiskStoreName(regionAttributes.getDiskStoreName()); + clientRegionFactory.setDiskSynchronous(regionAttributes.isDiskSynchronous()); + clientRegionFactory.setEntryIdleTimeout(regionAttributes.getEntryIdleTimeout()); + clientRegionFactory.setEntryTimeToLive(regionAttributes.getEntryTimeToLive()); + clientRegionFactory.setEvictionAttributes(regionAttributes.getEvictionAttributes()); + clientRegionFactory.setInitialCapacity(regionAttributes.getInitialCapacity()); + clientRegionFactory.setKeyConstraint(regionAttributes.getKeyConstraint()); + clientRegionFactory.setLoadFactor(regionAttributes.getLoadFactor()); + clientRegionFactory.setRegionIdleTimeout(regionAttributes.getRegionIdleTimeout()); + clientRegionFactory.setRegionTimeToLive(regionAttributes.getRegionTimeToLive()); + clientRegionFactory.setStatisticsEnabled(regionAttributes.getStatisticsEnabled()); + clientRegionFactory.setValueConstraint(regionAttributes.getValueConstraint()); + }); + + return Optional.ofNullable(regionAttributesPoolName.get()).filter(StringUtils::hasText); + } + /** * Post-process the given {@link ClientRegionFactory} setup by this {@link ClientRegionFactoryBean}. * @@ -445,7 +399,6 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean return region; } - /* (non-Javadoc) */ @SuppressWarnings("unchecked") private Region registerInterests(Region region) { @@ -459,6 +412,7 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean region.registerInterest(((Interest) interest).getKey(), interest.getPolicy(), interest.isDurable(), interest.isReceiveValues()); } + }); return region; @@ -488,18 +442,8 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean if (isDestroy()) { region.destroyRegion(); } - }); - } - /** - * Returns a reference to the Composite {@link RegionConfigurer} used to apply additional configuration - * to this {@link ClientRegionFactoryBean} on Spring container initialization. - * - * @return the Composite {@link RegionConfigurer}. - * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer - */ - protected RegionConfigurer getCompositeRegionConfigurer() { - return this.compositeRegionConfigurer; + }); } /** @@ -516,6 +460,17 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean this.attributes = attributes; } + /** + * Gets the {@link RegionAttributes} used to configure the {@link Region client Region} + * created by this {@link ClientRegionFactoryBean}. + * + * @return the {@link RegionAttributes} used to configure the {@link Region client Region}. + * @see org.apache.geode.cache.RegionAttributes + */ + protected RegionAttributes getAttributes() { + return this.attributes; + } + /** * Sets the cache listeners used for the region used by this factory. Used * only when a new region is created.Overrides the settings specified @@ -547,7 +502,10 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean this.cacheWriter = cacheWriter; } - /* (non-Javadoc) */ + public void setCloningEnabled(Boolean cloningEnabled) { + this.cloningEnabled = cloningEnabled; + } + final boolean isClose() { return this.close; } @@ -575,6 +533,22 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean this.compressor = compressor; } + public void setConcurrencyChecksEnabled(Boolean concurrencyChecksEnabled) { + this.concurrencyChecksEnabled = concurrencyChecksEnabled; + } + + public void setConcurrencyLevel(Integer concurrencyLevel) { + this.concurrencyLevel = concurrencyLevel; + } + + public void setCustomEntryIdleTimeout(CustomExpiry customEntryIdleTimeout) { + this.customEntryIdleTimeout = customEntryIdleTimeout; + } + + public void setCustomEntryTimeToLive(CustomExpiry customEntryTimeToLive) { + this.customEntryTimeToLive = customEntryTimeToLive; + } + /** * Sets the Data Policy. Used only when a new Region is created. * @@ -600,7 +574,6 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean setDataPolicy(resolvedDataPolicy); } - /* (non-Javadoc) */ final boolean isDestroy() { return this.destroy; } @@ -615,7 +588,7 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean */ public void setDestroy(boolean destroy) { this.destroy = destroy; - this.close = (this.close && !destroy); // retain previous value iff destroy is false; + this.close = this.close && !destroy; // retain previous value iff destroy is false; } /** @@ -627,10 +600,26 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean this.diskStoreName = diskStoreName; } + public void setDiskSynchronous(Boolean diskSynchronous) { + this.diskSynchronous = diskSynchronous; + } + + public void setEntryIdleTimeout(ExpirationAttributes entryIdleTimeout) { + this.entryIdleTimeout = entryIdleTimeout; + } + + public void setEntryTimeToLive(ExpirationAttributes entryTimeToLive) { + this.entryTimeToLive = entryTimeToLive; + } + public void setEvictionAttributes(EvictionAttributes evictionAttributes) { this.evictionAttributes = evictionAttributes; } + public void setInitialCapacity(Integer initialCapacity) { + this.initialCapacity = initialCapacity; + } + /** * Set the interests for this client region. Both key and regex interest are * supported. @@ -641,17 +630,22 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean this.interests = interests; } - /* (non-Javadoc) */ Interest[] getInterests() { return this.interests; } + /** + * Sets a {@link Class type} constraint on this {@link Region client Region's} keys. + * + * @param keyConstraint {@link Class type} of this {@link Region client Region's} keys. + * @see java.lang.Class + */ public void setKeyConstraint(Class keyConstraint) { this.keyConstraint = keyConstraint; } - protected boolean isPersistentUnspecified() { - return (persistent == null); + public void setLoadFactor(Float loadFactor) { + this.loadFactor = loadFactor; } protected boolean isPersistent() { @@ -662,14 +656,20 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean return Boolean.FALSE.equals(persistent); } - public void setPersistent(final boolean persistent) { + /** + * Configures whether this {@link Region client Region} is persistent, i.e. stores data to disk. + * + * @param persistent boolean value used to enable disk persistence. + */ + public void setPersistent(boolean persistent) { this.persistent = persistent; } /** - * Sets the {@link Pool} used by this client {@link Region}. + * Configures the {@link Pool} used by this {@link Region client Region}. * - * @param pool client {@link Pool} to be used by this client {@link Region}. + * @param pool {@link Pool} used by this {@link Region client Region} + * to send/receive data to/from the server. * @see org.apache.geode.cache.client.Pool * @see #setPoolName(String) */ @@ -678,9 +678,10 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean } /** - * Sets the {@link String name} of the {@link Pool} used by this client {@link Region}. + * Configures the {@link String name} of the {@link Pool} used by this {@link Region client Region}. * - * @param poolName {@link String} containing the name of the client {@link Pool} used by this client {@link Region}. + * @param poolName {@link String} containing the name of the client {@link Pool} + * used by this {@link Region client Region}. * @see #getPoolName() * @see #setPool(Pool) */ @@ -689,55 +690,44 @@ public class ClientRegionFactoryBean extends RegionLookupFactoryBean } /** - * Returns the {@link String name} of the configured {@link Pool} to use with this client {@link Region}. + * Returns the {@link String name} of the configured {@link Pool} to use with this {@link Region client Region}. * * @return the {@link Optional} {@link String name} of the configured {@link Pool} to use - * with this client {@link Region}. + * with this {@link Region client Region}. * @see #setPoolName(String) */ public Optional getPoolName() { return Optional.ofNullable(this.poolName); } - /** - * Null-safe operation to set an array of {@link RegionConfigurer RegionConfigurers} used to apply - * additional configuration to this {@link ClientRegionFactoryBean} when using Annotation-based configuration. - * - * @param regionConfigurers array of {@link RegionConfigurer RegionConfigurers} used to apply - * additional configuration to this {@link ClientRegionFactoryBean}. - * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer - * @see #setRegionConfigurers(List) - */ - public void setRegionConfigurers(RegionConfigurer... regionConfigurers) { - setRegionConfigurers(Arrays.asList(nullSafeArray(regionConfigurers, RegionConfigurer.class))); + public void setRegionIdleTimeout(ExpirationAttributes regionIdleTimeout) { + this.regionIdleTimeout = regionIdleTimeout; + } + + public void setRegionTimeToLive(ExpirationAttributes regionTimeToLive) { + this.regionTimeToLive = regionTimeToLive; } /** - * Null-safe operation to set an {@link Iterable} of {@link RegionConfigurer RegionConfigurers} used to apply - * additional configuration to this {@link ClientRegionFactoryBean} when using Annotation-based configuration. + * Initializes the {@link DataPolicy} of the {@link Region client Region} + * using the given {@link ClientRegionShortcut}. * - * @param regionConfigurers {@link Iterable} of {@link RegionConfigurer RegionConfigurers} used to apply - * additional configuration to this {@link ClientRegionFactoryBean}. - * @see org.springframework.data.gemfire.config.annotation.RegionConfigurer - */ - public void setRegionConfigurers(List regionConfigurers) { - this.regionConfigurers = Optional.ofNullable(regionConfigurers).orElseGet(Collections::emptyList); - } - - /** - * Initializes the client {@link Region} using the given {@link ClientRegionShortcut}. - * - * @param shortcut {@link ClientRegionShortcut} used to initialize this client {@link Region}. + * @param shortcut {@link ClientRegionShortcut} used to initialize the {@link DataPolicy} + * of this {@link Region client Region}. * @see org.apache.geode.cache.client.ClientRegionShortcut */ public void setShortcut(ClientRegionShortcut shortcut) { this.shortcut = shortcut; } + public void setStatisticsEnabled(Boolean statisticsEnabled) { + this.statisticsEnabled = statisticsEnabled; + } + /** - * Sets a {@link Class type} constraint on this {@link Region Region's} values. + * Sets a {@link Class type} constraint on this {@link Region client Region's} values. * - * @param valueConstraint {@link Class type} of this client {@link Region Region's} values. + * @param valueConstraint {@link Class type} of this {@link Region client Region's} values. * @see java.lang.Class */ public void setValueConstraint(Class valueConstraint) { diff --git a/src/main/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessor.java b/src/main/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessor.java index 38015b1c..4b05eb7f 100644 --- a/src/main/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessor.java +++ b/src/main/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessor.java @@ -16,15 +16,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.geode.cache.Region; import org.apache.geode.cache.client.ClientCache; import org.apache.geode.cache.client.ClientRegionFactory; import org.apache.geode.cache.client.ClientRegionShortcut; import org.apache.geode.cache.execute.Function; import org.apache.geode.management.internal.cli.domain.RegionInformation; import org.apache.geode.management.internal.cli.functions.GetRegionsFunction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; @@ -52,7 +51,7 @@ import org.springframework.util.ObjectUtils; */ public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor { - protected final Log logger = LogFactory.getLog(getClass()); + protected final Logger logger = LoggerFactory.getLogger(getClass()); private final ClientCache clientCache; @@ -64,7 +63,10 @@ public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor * @param clientCache the GemFire ClientCache instance. * @see org.apache.geode.cache.client.ClientCache */ - public GemfireDataSourcePostProcessor(final ClientCache clientCache) { + public GemfireDataSourcePostProcessor(ClientCache clientCache) { + + Assert.notNull(clientCache, "ClientCache must not be null"); + this.clientCache = clientCache; } @@ -77,21 +79,24 @@ public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor createClientRegionProxies(beanFactory, regionNames()); } - /* (non-Javadoc) */ - // TODO remove this logic and delegate to o.s.d.g.config.remote.GemfireAdminOperations + // TODO: remove this logic and delegate to o.s.d.g.config.remote.GemfireAdminOperations Iterable regionNames() { + try { return execute(new ListRegionsOnServerFunction()); } catch (Exception ignore) { try { + Object results = execute(new GetRegionsFunction()); + List regionNames = Collections.emptyList(); if (containsRegionInformation(results)) { + Object[] resultsArray = (Object[]) results; - regionNames = new ArrayList(resultsArray.length); + regionNames = new ArrayList<>(resultsArray.length); for (Object result : resultsArray) { regionNames.add(((RegionInformation) result).getName()); @@ -100,39 +105,42 @@ public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor return regionNames; } - catch (Exception e) { - log("Failed to determine the Regions available on the Server: %n%1$s", e); + catch (Exception cause) { + log("Failed to determine the Regions available on the Server: %n%1$s", cause); return Collections.emptyList(); } } } - /* (non-Javadoc) */ @SuppressWarnings("unchecked") T execute(Function gemfireFunction, Object... arguments) { - return new GemfireOnServersFunctionTemplate(clientCache).executeAndExtract(gemfireFunction, arguments); + return new GemfireOnServersFunctionTemplate(this.clientCache).executeAndExtract(gemfireFunction, arguments); } - /* (non-Javadoc) */ boolean containsRegionInformation(Object results) { - return (results instanceof Object[] && ((Object[]) results).length > 0 - && ((Object[]) results)[0] instanceof RegionInformation); + return results instanceof Object[] && ((Object[]) results).length > 0 + && ((Object[]) results)[0] instanceof RegionInformation; } - /* (non-Javadoc) */ void createClientRegionProxies(ConfigurableListableBeanFactory beanFactory, Iterable regionNames) { + if (regionNames.iterator().hasNext()) { - ClientRegionFactory clientRegionFactory = clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY); + + ClientRegionFactory clientRegionFactory = + this.clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY); for (String regionName : regionNames) { + boolean createRegion = true; if (beanFactory.containsBean(regionName)) { + Object existingBean = beanFactory.getBean(regionName); - Assert.isTrue(existingBean instanceof Region, String.format( - "Cannot create a client PROXY Region bean named '%1$s'. A bean with this name of type '%2$s' already exists.", - regionName, ObjectUtils.nullSafeClassName(existingBean))); + if (logger.isWarnEnabled()) { + logger.warn("Cannot create a client PROXY Region bean named {}; A bean with name {} having type {} already exists", + regionName, regionName, ObjectUtils.nullSafeClassName(existingBean)); + } createRegion = false; } @@ -142,17 +150,15 @@ public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor beanFactory.registerSingleton(regionName, clientRegionFactory.create(regionName)); } else { - log("A Region with name '%s' is already defined.", regionName); + log("A Region with name '%s' is already defined", regionName); } } } } - /* (non-Javadoc) */ void log(String message, Object... arguments) { if (logger.isDebugEnabled()) { logger.debug(String.format(message, arguments)); } } - } diff --git a/src/main/java/org/springframework/data/gemfire/client/PoolAdapter.java b/src/main/java/org/springframework/data/gemfire/client/PoolAdapter.java index b57285ab..ca34dd10 100644 --- a/src/main/java/org/springframework/data/gemfire/client/PoolAdapter.java +++ b/src/main/java/org/springframework/data/gemfire/client/PoolAdapter.java @@ -24,13 +24,13 @@ import org.apache.geode.cache.client.Pool; import org.apache.geode.cache.query.QueryService; /** - * The PoolAdapter class is an abstract, default no-op implementation of the GemFire {@link Pool} interface - * that conveniently enables implementing classes to extend this adapter to adapt their interfaces and serve - * as a {@link Pool}. + * The {@link PoolAdapter} class is an abstract base class and default, no-op implementation of + * the {@link Pool} interface that conveniently enables implementing classes to extend this adapter + * and choose which {@link Pool} methods/operations are supported by this implementation. * * For instance, one possible implementation is Spring Data GemFire's {@link PoolFactoryBean}, which can act as * a {@link Pool} in a context where only the {@link Pool}'s "configuration" and meta-data are required, - * but not actual connections or operating state information (e.g. pendingEventCount). + * but no actual connections or operating state information (e.g. pendingEventCount) is needed. * * @author John Blum * @see org.springframework.data.gemfire.client.PoolFactoryBean @@ -42,148 +42,119 @@ public abstract class PoolAdapter implements Pool { public static final String NOT_IMPLEMENTED = "Not Implemented"; - /* (non-Javadoc) */ public boolean isDestroyed() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getFreeConnectionTimeout() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public long getIdleTimeout() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getLoadConditioningInterval() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public List getLocators() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getMaxConnections() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getMinConnections() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public boolean getMultiuserAuthentication() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public String getName() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ @Override public List getOnlineLocators() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getPendingEventCount() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public long getPingInterval() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public boolean getPRSingleHopEnabled() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public QueryService getQueryService() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getReadTimeout() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getRetryAttempts() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public String getServerGroup() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public List getServers() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getSocketBufferSize() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getSocketConnectTimeout() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getStatisticInterval() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getSubscriptionAckInterval() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public boolean getSubscriptionEnabled() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getSubscriptionMessageTrackingTimeout() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public int getSubscriptionRedundancy() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public boolean getThreadLocalConnections() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public void destroy() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ - public void destroy(final boolean keepAlive) { + public void destroy(boolean keepAlive) { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } - /* (non-Javadoc) */ public void releaseThreadLocalConnection() { throw new UnsupportedOperationException(NOT_IMPLEMENTED); } 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 6b6d1cf3..a23ccc09 100644 --- a/src/main/java/org/springframework/data/gemfire/client/PoolFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/PoolFactoryBean.java @@ -21,6 +21,7 @@ import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeCollection; import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeIterable; import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; +import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException; import java.net.InetSocketAddress; import java.util.Arrays; @@ -75,8 +76,8 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements protected static final int DEFAULT_LOCATOR_PORT = DistributedSystemUtils.DEFAULT_LOCATOR_PORT; protected static final int DEFAULT_SERVER_PORT = DistributedSystemUtils.DEFAULT_CACHE_SERVER_PORT; - // indicates whether the Pool has been created internally (by this FactoryBean) or not - volatile boolean springBasedPool = true; + // Indicates whether the Pool has been created by this FactoryBean, or not + volatile boolean springManagedPool = true; // GemFire Pool Configuration Settings private boolean keepAlive = false; @@ -109,7 +110,7 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements private volatile Pool pool; private PoolConfigurer compositePoolConfigurer = (beanName, bean) -> - nullSafeCollection(poolConfigurers).forEach(poolConfigurer -> poolConfigurer.configure(beanName, bean)); + nullSafeCollection(poolConfigurers).forEach(poolConfigurer -> poolConfigurer.configure(beanName, bean)); private PoolFactoryInitializer poolFactoryInitializer; @@ -123,33 +124,44 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements * @see org.apache.geode.cache.client.PoolManager * @see org.apache.geode.cache.client.PoolFactory * @see org.apache.geode.cache.client.Pool + * @see #resolvePoolName() */ @Override public void afterPropertiesSet() throws Exception { - init(Optional.ofNullable(PoolManager.find(validatePoolName()))); - } - /* (non-Javadoc) */ - @SuppressWarnings("all") - private void init(Optional existingPool) { + Pool existingPool = find(resolvePoolName()); - if (existingPool.isPresent()) { - this.pool = existingPool.get(); - this.springBasedPool = false; + if (existingPool != null) { - logDebug(() -> String.format( - "Pool with name [%s] already exists; Using existing Pool; Pool Configurers [%d] will not be applied", - existingPool.get().getName(), this.poolConfigurers.size())); + this.pool = existingPool; + this.springManagedPool = false; + + logDebug(() -> String.format("A Pool with name [%s] already exists; Using existing Pool", + this.pool.getName())); + + logDebug("PoolConfigurers will not be applied"); } else { - this.springBasedPool = true; + logDebug("Pool [%s] not found; Lazily creating new Pool...", getName()); applyPoolConfigurers(); - - logDebug("No Pool with name [%s] was found; Creating new Pool", getName()); } } - /* (non-Javadoc) */ + private String resolvePoolName() { + + if (!StringUtils.hasText(getName())) { + setName(Optional.ofNullable(getBeanName()) + .filter(StringUtils::hasText) + .orElseThrow(() -> newIllegalArgumentException("Pool name is required"))); + } + + return getName(); + } + + private Pool find(String name) { + return PoolManager.find(name); + } + private void applyPoolConfigurers() { applyPoolConfigurers(getCompositePoolConfigurer()); } @@ -179,17 +191,6 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements .forEach(poolConfigurer -> poolConfigurer.configure(getName(), this)); } - /* (non-Javadoc) */ - private String validatePoolName() { - - if (!StringUtils.hasText(getName())) { - setName(Optional.ofNullable(getBeanName()).filter(StringUtils::hasText) - .orElseThrow(() -> newIllegalArgumentException("Pool name is required"))); - } - - return getName(); - } - /** * Releases all system resources and destroys the {@link Pool} when created by this {@link PoolFactoryBean}. * @@ -200,7 +201,7 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements public void destroy() throws Exception { Optional.ofNullable(this.pool) - .filter(pool -> this.springBasedPool) + .filter(pool -> this.springManagedPool) .filter(pool -> !pool.isDestroyed()) .ifPresent(pool -> { pool.releaseThreadLocalConnection(); @@ -210,17 +211,6 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements }); } - /** - * Returns a reference to the Composite {@link PoolConfigurer} used to apply additional configuration - * to this {@link PoolFactoryBean} on Spring container initialization. - * - * @return the Composite {@link PoolConfigurer}. - * @see org.springframework.data.gemfire.config.annotation.PoolConfigurer - */ - protected PoolConfigurer getCompositePoolConfigurer() { - return this.compositePoolConfigurer; - } - /** * Returns an object reference to the {@link Pool} created by this {@link PoolFactoryBean}. * @@ -233,28 +223,17 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements return Optional.ofNullable(this.pool).orElseGet(() -> { - eagerlyInitializeClientCacheIfNotPresent(); + eagerlyInitializeClientCache(); - PoolFactory poolFactory = configure(initialize(createPoolFactory())); + Pool namedPool = find(getName()); - this.pool = create(poolFactory, getName()); + this.pool = namedPool != null ? namedPool + : postProcess(create(postProcess(configure(initialize(createPoolFactory()))), getName())); return this.pool; }); } - /** - * Determines whether the {@link DistributedSystem} exists yet or not. - * - * @return a boolean value indicating whether the single, {@link DistributedSystem} has already been created. - * @see org.springframework.data.gemfire.GemfireUtils#getDistributedSystem() - * @see org.springframework.data.gemfire.GemfireUtils#isConnected(DistributedSystem) - * @see org.apache.geode.distributed.DistributedSystem - */ - boolean isDistributedSystemPresent() { - return GemfireUtils.isConnected(GemfireUtils.getDistributedSystem()); - } - /** * Attempts to eagerly initialize the {@link ClientCache} if not already present so that a single * {@link DistributedSystem} will exist, which is required to create a {@link Pool} instance. @@ -262,14 +241,33 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements * @see org.springframework.beans.factory.BeanFactory#getBean(Class) * @see org.apache.geode.cache.client.ClientCache * @see org.apache.geode.distributed.DistributedSystem - * @see #isDistributedSystemPresent() + * @see #isClientCachePresent() */ - private void eagerlyInitializeClientCacheIfNotPresent() { - if (!isDistributedSystemPresent()) { + private void eagerlyInitializeClientCache() { + + if (!isClientCachePresent()) { getBeanFactory().getBean(ClientCache.class); } } + /** + * Determines whether the {@link ClientCache} exists yet or not. + * + * @return a boolean value indicating whether the single {@link ClientCache} instance + * has been created yet. + * @see org.springframework.data.gemfire.GemfireUtils#getClientCache() + * @see org.apache.geode.distributed.DistributedSystem + * @see org.apache.geode.cache.client.ClientCache + */ + boolean isClientCachePresent() { + + return Optional.ofNullable(GemfireUtils.getClientCache()) + .filter(clientCache -> !clientCache.isClosed()) + .map(ClientCache::getDistributedSystem) + .filter(GemfireUtils::isConnected) + .isPresent(); + } + /** * Creates an instance of the {@link PoolFactory} interface to construct, configure and initialize a {@link Pool}. * @@ -336,6 +334,17 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements .orElse(poolFactory); } + /** + * Post processes the fully configured {@link PoolFactory}. + * + * @param poolFactory {@link PoolFactory} to post process. + * @return the post processed {@link PoolFactory}. + * @see org.apache.geode.cache.client.PoolFactory + */ + protected PoolFactory postProcess(PoolFactory poolFactory) { + return poolFactory; + } + /** * Creates a {@link Pool} with the given {@link String name} using the provided {@link PoolFactory}. * @@ -350,61 +359,77 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements } /** - * Returns the {@link Class} type of the {@link Pool} produced by this {@link PoolFactoryBean}. + * Post processes the {@link Pool} created by this {@link PoolFactoryBean}. * - * @return the {@link Class} type of the {@link Pool} produced by this {@link PoolFactoryBean}. + * @param pool {@link Pool} to post process. + * @return the post processed {@link Pool}. + * @see org.apache.geode.cache.client.Pool + */ + protected Pool postProcess(Pool pool) { + return pool; + } + + /** + * Returns the {@link Class type} of {@link Pool} produced by this {@link PoolFactoryBean}. + * + * @return the {@link Class type} of {@link Pool} produced by this {@link PoolFactoryBean}. * @see org.springframework.beans.factory.FactoryBean#getObjectType() */ @Override @SuppressWarnings("unchecked") public Class getObjectType() { - return Optional.ofNullable(this.pool).map(Pool::getClass).orElse((Class) Pool.class); + return this.pool != null ? this.pool.getClass() : Pool.class; } - /* (non-Javadoc) */ public void addLocators(ConnectionEndpoint... locators) { this.locators.add(locators); } - /* (non-Javadoc) */ public void addLocators(Iterable locators) { this.locators.add(locators); } - /* (non-Javadoc) */ public void addServers(ConnectionEndpoint... servers) { this.servers.add(servers); } - /* (non-Javadoc) */ public void addServers(Iterable servers) { this.servers.add(servers); } - /* (non-Javadoc) */ + /** + * Returns a reference to the Composite {@link PoolConfigurer} used to apply additional configuration + * to this {@link PoolFactoryBean} on Spring container initialization. + * + * @return the Composite {@link PoolConfigurer}. + * @see org.springframework.data.gemfire.config.annotation.PoolConfigurer + */ + protected PoolConfigurer getCompositePoolConfigurer() { + return this.compositePoolConfigurer; + } + public void setName(String name) { this.name = name; } - /* (non-Javadoc) */ protected String getName() { return this.name; } - /* (non-Javadoc) */ public void setPool(Pool pool) { this.pool = pool; } - /* (non-Javadoc) */ public Pool getPool() { return Optional.ofNullable(this.pool).orElseGet(() -> new PoolAdapter() { @Override public boolean isDestroyed() { + Pool pool = PoolFactoryBean.this.pool; - return (pool != null && pool.isDestroyed()); + + return pool != null && pool.isDestroyed(); } @Override @@ -429,8 +454,10 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements @Override public List getOnlineLocators() { - return Optional.ofNullable(PoolFactoryBean.this.pool).map(Pool::getOnlineLocators) - .orElseThrow(() -> new IllegalStateException("The Pool has not been initialized")); + + return Optional.ofNullable(PoolFactoryBean.this.pool) + .map(Pool::getOnlineLocators) + .orElseThrow(() -> newIllegalStateException("Pool [%s] has not been initialized", getName())); } @Override @@ -450,14 +477,18 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements @Override public String getName() { - return Optional.ofNullable(PoolFactoryBean.this.getName()).filter(StringUtils::hasText) + + return Optional.ofNullable(PoolFactoryBean.this.getName()) + .filter(StringUtils::hasText) .orElseGet(PoolFactoryBean.this::getBeanName); } @Override public int getPendingEventCount() { - return Optional.ofNullable(PoolFactoryBean.this.pool).map(Pool::getPendingEventCount) - .orElseThrow(() -> new IllegalStateException("The Pool has not been initialized")); + + return Optional.ofNullable(PoolFactoryBean.this.pool) + .map(Pool::getPendingEventCount) + .orElseThrow(() -> newIllegalStateException("Pool [%s] has not been initialized", getName())); } @Override @@ -472,8 +503,10 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements @Override public QueryService getQueryService() { - return Optional.ofNullable(PoolFactoryBean.this.pool).map(Pool::getQueryService) - .orElseThrow(() -> new IllegalStateException("The Pool has not been initialized")); + + return Optional.ofNullable(PoolFactoryBean.this.pool) + .map(Pool::getQueryService) + .orElseThrow(() -> newIllegalStateException("Pool [%s] has not been initialized", getName())); } @Override @@ -543,6 +576,7 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements @Override public void destroy(boolean keepAlive) { + try { PoolFactoryBean.this.destroy(); } @@ -553,70 +587,58 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements @Override public void releaseThreadLocalConnection() { - Pool pool = PoolFactoryBean.this.pool; - if (pool != null) { - pool.releaseThreadLocalConnection(); - } - else { - throw new IllegalStateException("The Pool has not been initialized"); - } + Optional.ofNullable(PoolFactoryBean.this.pool) + .map(it -> { + it.releaseThreadLocalConnection(); + return it; + }) + .orElseThrow(() -> newIllegalStateException("Pool [%s] has not been initialized", getName())); } }); } - /* (non-Javadoc) */ public void setFreeConnectionTimeout(int freeConnectionTimeout) { this.freeConnectionTimeout = freeConnectionTimeout; } - /* (non-Javadoc) */ public void setIdleTimeout(long idleTimeout) { this.idleTimeout = idleTimeout; } - /* (non-Javadoc) */ public void setKeepAlive(boolean keepAlive) { this.keepAlive = keepAlive; } - /* (non-Javadoc) */ public void setLoadConditioningInterval(int loadConditioningInterval) { this.loadConditioningInterval = loadConditioningInterval; } - /* (non-Javadoc) */ public void setLocators(ConnectionEndpoint[] connectionEndpoints) { setLocators(ConnectionEndpointList.from(connectionEndpoints)); } - /* (non-Javadoc) */ public void setLocators(Iterable connectionEndpoints) { getLocators().clear(); getLocators().add(connectionEndpoints); } - /* (non-Javadoc) */ ConnectionEndpointList getLocators() { return locators; } - /* (non-Javadoc) */ public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; } - /* (non-Javadoc) */ public void setMinConnections(int minConnections) { this.minConnections = minConnections; } - /* (non-Javadoc) */ public void setMultiUserAuthentication(boolean multiUserAuthentication) { this.multiUserAuthentication = multiUserAuthentication; } - /* (non-Javadoc) */ public void setPingInterval(long pingInterval) { this.pingInterval = pingInterval; } @@ -658,78 +680,63 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport implements this.poolFactoryInitializer = poolFactoryInitializer; } - /* (non-Javadoc) */ public void setPrSingleHopEnabled(boolean prSingleHopEnabled) { this.prSingleHopEnabled = prSingleHopEnabled; } - /* (non-Javadoc) */ public void setReadTimeout(int readTimeout) { this.readTimeout = readTimeout; } - /* (non-Javadoc) */ public void setRetryAttempts(int retryAttempts) { this.retryAttempts = retryAttempts; } - /* (non-Javadoc) */ public void setServerGroup(String serverGroup) { this.serverGroup = serverGroup; } - /* (non-Javadoc) */ public void setServers(ConnectionEndpoint[] connectionEndpoints) { setServers(ConnectionEndpointList.from(connectionEndpoints)); } - /* (non-Javadoc) */ public void setServers(Iterable connectionEndpoints) { getServers().clear(); getServers().add(connectionEndpoints); } - /* (non-Javadoc) */ ConnectionEndpointList getServers() { return servers; } - /* (non-Javadoc) */ public void setSocketBufferSize(int socketBufferSize) { this.socketBufferSize = socketBufferSize; } - /* (non-Javadoc) */ public void setSocketConnectTimeout(int socketConnectTimeout) { this.socketConnectTimeout = socketConnectTimeout; } - /* (non-Javadoc) */ public void setStatisticInterval(int statisticInterval) { this.statisticInterval = statisticInterval; } - /* (non-Javadoc) */ public void setSubscriptionAckInterval(int subscriptionAckInterval) { this.subscriptionAckInterval = subscriptionAckInterval; } - /* (non-Javadoc) */ public void setSubscriptionEnabled(boolean subscriptionEnabled) { this.subscriptionEnabled = subscriptionEnabled; } - /* (non-Javadoc) */ public void setSubscriptionMessageTrackingTimeout(int subscriptionMessageTrackingTimeout) { this.subscriptionMessageTrackingTimeout = subscriptionMessageTrackingTimeout; } - /* (non-Javadoc) */ public void setSubscriptionRedundancy(int subscriptionRedundancy) { this.subscriptionRedundancy = subscriptionRedundancy; } - /* (non-Javadoc) */ public void setThreadLocalConnections(boolean threadLocalConnections) { this.threadLocalConnections = threadLocalConnections; } diff --git a/src/main/java/org/springframework/data/gemfire/client/support/DefaultableDelegatingPoolAdapter.java b/src/main/java/org/springframework/data/gemfire/client/support/DefaultableDelegatingPoolAdapter.java index 8322136e..4ac4253b 100644 --- a/src/main/java/org/springframework/data/gemfire/client/support/DefaultableDelegatingPoolAdapter.java +++ b/src/main/java/org/springframework/data/gemfire/client/support/DefaultableDelegatingPoolAdapter.java @@ -20,15 +20,18 @@ package org.springframework.data.gemfire.client.support; import java.net.InetSocketAddress; import java.util.Collection; import java.util.List; +import java.util.function.Supplier; import org.apache.geode.cache.client.Pool; import org.apache.geode.cache.query.QueryService; +import org.apache.shiro.util.CollectionUtils; import org.springframework.data.gemfire.util.SpringUtils; import org.springframework.util.Assert; /** - * The DefaultableDelegatingPoolAdapter class is a wrapper class around Pool allowing default configuration property - * values to be providing in the case that the Pool's setting were null. + * The {@link DefaultableDelegatingPoolAdapter} class is a wrapper class around {@link Pool} + * allowing default configuration property values to be provided in the case that the {@link Pool Pool's} + * settings were {@literal null}. * * @author John Blum * @see org.apache.geode.cache.client.Pool @@ -41,221 +44,178 @@ public abstract class DefaultableDelegatingPoolAdapter { private Preference preference = Preference.PREFER_POOL; - /* (non-Javadoc) */ public static DefaultableDelegatingPoolAdapter from(Pool delegate) { - return new DefaultableDelegatingPoolAdapter(delegate) { }; + return new DefaultableDelegatingPoolAdapter(delegate) {}; } - /* (non-Javadoc) */ protected DefaultableDelegatingPoolAdapter(Pool delegate) { - Assert.notNull(delegate, "'delegate' must not be null"); + Assert.notNull(delegate, "Pool delegate must not be null"); this.delegate = delegate; } - /* (non-Javadoc) */ protected Pool getDelegate() { return this.delegate; } - /* (non-Javadoc) */ protected DefaultableDelegatingPoolAdapter setPreference(Preference preference) { this.preference = preference; return this; } - /* (non-Javadoc) */ protected Preference getPreference() { return this.preference; } - /* (non-Javadoc) */ - protected T defaultIfNull(T defaultValue, ValueProvider valueProvider) { - return (prefersPool() ? SpringUtils.defaultIfNull(valueProvider.getValue(), defaultValue) : - (defaultValue != null ? defaultValue : valueProvider.getValue())); + protected T defaultIfNull(T defaultValue, Supplier valueProvider) { + + return prefersPool() ? SpringUtils.defaultIfNull(valueProvider.get(), defaultValue) : + (defaultValue != null ? defaultValue : valueProvider.get()); } - /* (non-Javadoc) */ - protected > T defaultIfEmpty(T defaultValue, ValueProvider valueProvider) { + protected > T defaultIfEmpty(T defaultValue, Supplier valueProvider) { if (prefersPool()) { - T value = valueProvider.getValue(); - return (value == null || value.isEmpty() ? defaultValue : value); + T value = valueProvider.get(); + return CollectionUtils.isEmpty(value) ? defaultValue : value; } else { - return (defaultValue == null || defaultValue.isEmpty() ? valueProvider.getValue() : defaultValue); + return CollectionUtils.isEmpty(defaultValue) ? valueProvider.get() : defaultValue; } } - /* (non-Javadoc) */ public DefaultableDelegatingPoolAdapter preferDefault() { return setPreference(Preference.PREFER_DEFAULT); } - /* (non-Javadoc) */ protected boolean prefersDefault() { return Preference.PREFER_DEFAULT.equals(getPreference()); } - /* (non-Javadoc) */ public DefaultableDelegatingPoolAdapter preferPool() { return setPreference(Preference.PREFER_POOL); } - /* (non-Javadoc) */ protected boolean prefersPool() { return Preference.PREFER_POOL.equals(getPreference()); } - /* (non-Javadoc) */ public boolean isDestroyed() { return getDelegate().isDestroyed(); } - /* (non-Javadoc) */ public int getFreeConnectionTimeout(Integer defaultFreeConnectionTimeout) { return defaultIfNull(defaultFreeConnectionTimeout, () -> getDelegate().getFreeConnectionTimeout()); } - /* (non-Javadoc) */ public long getIdleTimeout(Long defaultIdleTimeout) { return defaultIfNull(defaultIdleTimeout, () -> getDelegate().getIdleTimeout()); } - /* (non-Javadoc) */ public int getLoadConditioningInterval(Integer defaultLoadConditioningInterval) { return defaultIfNull(defaultLoadConditioningInterval, () -> getDelegate().getLoadConditioningInterval()); } - /* (non-Javadoc) */ public List getLocators(List defaultLocators) { return defaultIfEmpty(defaultLocators, () -> getDelegate().getLocators()); } - /* (non-Javadoc) */ public int getMaxConnections(Integer defaultMaxConnections) { return defaultIfNull(defaultMaxConnections, () -> getDelegate().getMaxConnections()); } - /* (non-Javadoc) */ public int getMinConnections(Integer defaultMinConnections) { return defaultIfNull(defaultMinConnections, () -> getDelegate().getMinConnections()); } - /* (non-Javadoc) */ public boolean getMultiuserAuthentication(Boolean defaultMultiUserAuthentication) { return defaultIfNull(defaultMultiUserAuthentication, () -> getDelegate().getMultiuserAuthentication()); } - /* (non-Javadoc) */ public String getName() { return getDelegate().getName(); } - /* (non-Javadoc) */ public int getPendingEventCount() { return getDelegate().getPendingEventCount(); } - /* (non-Javadoc) */ public long getPingInterval(Long defaultPingInterval) { return defaultIfNull(defaultPingInterval, () -> getDelegate().getPingInterval()); } - /* (non-Javadoc) */ public boolean getPRSingleHopEnabled(Boolean defaultPrSingleHopEnabled) { return defaultIfNull(defaultPrSingleHopEnabled, () -> getDelegate().getPRSingleHopEnabled()); } - /* (non-Javadoc) */ public QueryService getQueryService(QueryService defaultQueryService) { return defaultIfNull(defaultQueryService, () -> getDelegate().getQueryService()); } - /* (non-Javadoc) */ public int getReadTimeout(Integer defaultReadTimeout) { return defaultIfNull(defaultReadTimeout, () -> getDelegate().getReadTimeout()); } - /* (non-Javadoc) */ public int getRetryAttempts(Integer defaultRetryAttempts) { return defaultIfNull(defaultRetryAttempts, () -> getDelegate().getRetryAttempts()); } - /* (non-Javadoc) */ public String getServerGroup(String defaultServerGroup) { return defaultIfNull(defaultServerGroup, () -> getDelegate().getServerGroup()); } - /* (non-Javadoc) */ public List getServers(List defaultServers) { return defaultIfEmpty(defaultServers, () -> getDelegate().getServers()); } - /* (non-Javadoc) */ public int getSocketBufferSize(Integer defaultSocketBufferSize) { return defaultIfNull(defaultSocketBufferSize, () -> getDelegate().getSocketBufferSize()); } - /* (non-Javadoc) */ public int getSocketConnectTimeout(Integer defaultSocketConnectTimeout) { return defaultIfNull(defaultSocketConnectTimeout, () -> getDelegate().getSocketConnectTimeout()); } - /* (non-Javadoc) */ public int getStatisticInterval(Integer defaultStatisticInterval) { return defaultIfNull(defaultStatisticInterval, () -> getDelegate().getStatisticInterval()); } - /* (non-Javadoc) */ public int getSubscriptionAckInterval(Integer defaultSubscriptionAckInterval) { return defaultIfNull(defaultSubscriptionAckInterval, () -> getDelegate().getSubscriptionAckInterval()); } - /* (non-Javadoc) */ public boolean getSubscriptionEnabled(Boolean defaultSubscriptionEnabled) { return defaultIfNull(defaultSubscriptionEnabled, () -> getDelegate().getSubscriptionEnabled()); } - /* (non-Javadoc) */ public int getSubscriptionMessageTrackingTimeout(Integer defaultSubscriptionMessageTrackingTimeout) { return defaultIfNull(defaultSubscriptionMessageTrackingTimeout, () -> getDelegate().getSubscriptionMessageTrackingTimeout()); } - /* (non-Javadoc) */ public int getSubscriptionRedundancy(Integer defaultSubscriptionRedundancy) { return defaultIfNull(defaultSubscriptionRedundancy, () -> getDelegate().getSubscriptionRedundancy()); } - /* (non-Javadoc) */ public boolean getThreadLocalConnections(Boolean defaultThreadLocalConnections) { return defaultIfNull(defaultThreadLocalConnections, () -> getDelegate().getThreadLocalConnections()); } - /* (non-Javadoc) */ public void destroy() { getDelegate().destroy(); } - /* (non-Javadoc) */ - public void destroy(final boolean keepAlive) { + public void destroy(boolean keepAlive) { getDelegate().destroy(keepAlive); } - /* (non-Javadoc) */ public void releaseThreadLocalConnection() { getDelegate().releaseThreadLocalConnection(); } - /* (non-Javadoc) */ enum Preference { PREFER_DEFAULT, PREFER_POOL - } - /* (non-Javadoc) */ - interface ValueProvider { - T getValue(); } } diff --git a/src/main/java/org/springframework/data/gemfire/client/support/DelegatingPoolAdapter.java b/src/main/java/org/springframework/data/gemfire/client/support/DelegatingPoolAdapter.java index 04cc5388..e26656d6 100644 --- a/src/main/java/org/springframework/data/gemfire/client/support/DelegatingPoolAdapter.java +++ b/src/main/java/org/springframework/data/gemfire/client/support/DelegatingPoolAdapter.java @@ -25,7 +25,7 @@ import org.apache.geode.cache.client.Pool; import org.apache.geode.cache.query.QueryService; /** - * DelegatingPoolAdapter is an abstract implementation of GemFire's {@link Pool} interface and extension of + * {@link DelegatingPoolAdapter} is an abstract implementation of GemFire's {@link Pool} interface and extension of * {@link FactoryDefaultsPoolAdapter} that delegates operations to the provided {@link Pool} instance. * * However, this implementation guards against a potentially null {@link Pool} reference by returning @@ -33,8 +33,9 @@ import org.apache.geode.cache.query.QueryService; * when the {@link Pool} reference is null. * * @author John Blum - * @see org.springframework.data.gemfire.client.support.FactoryDefaultsPoolAdapter * @see org.apache.geode.cache.client.Pool + * @see org.apache.geode.cache.query.QueryService + * @see org.springframework.data.gemfire.client.support.FactoryDefaultsPoolAdapter * @since 1.8.0 */ @SuppressWarnings("unused") @@ -42,9 +43,8 @@ public abstract class DelegatingPoolAdapter extends FactoryDefaultsPoolAdapter { private final Pool delegate; - /* (non-Javadoc) */ public static DelegatingPoolAdapter from(Pool delegate) { - return new DelegatingPoolAdapter(delegate) { }; + return new DelegatingPoolAdapter(delegate) {}; } /** @@ -57,191 +57,225 @@ public abstract class DelegatingPoolAdapter extends FactoryDefaultsPoolAdapter { this.delegate = delegate; } - /* (non-Javadoc) */ protected Pool getDelegate() { - return delegate; + return this.delegate; } - /* (non-Javadoc) */ @Override public boolean isDestroyed() { return Optional.ofNullable(getDelegate()).map(Pool::isDestroyed).orElseGet(super::isDestroyed); } - /* (non-Javadoc) */ @Override public int getFreeConnectionTimeout() { - return Optional.ofNullable(getDelegate()).map(Pool::getFreeConnectionTimeout) + + return Optional.ofNullable(getDelegate()) + .map(Pool::getFreeConnectionTimeout) .orElseGet(super::getFreeConnectionTimeout); } - /* (non-Javadoc) */ @Override public long getIdleTimeout() { - return Optional.ofNullable(getDelegate()).map(Pool::getIdleTimeout).orElseGet(super::getIdleTimeout); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getIdleTimeout) + .orElseGet(super::getIdleTimeout); } - /* (non-Javadoc) */ @Override public int getLoadConditioningInterval() { - return Optional.ofNullable(getDelegate()).map(Pool::getLoadConditioningInterval) + + return Optional.ofNullable(getDelegate()) + .map(Pool::getLoadConditioningInterval) .orElseGet(super::getLoadConditioningInterval); } - /* (non-Javadoc) */ @Override public List getLocators() { - return Optional.ofNullable(getDelegate()).map(Pool::getLocators).orElseGet(super::getLocators); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getLocators) + .orElseGet(super::getLocators); } - /* (non-Javadoc) */ @Override public int getMaxConnections() { - return Optional.ofNullable(getDelegate()).map(Pool::getMaxConnections).orElseGet(super::getMaxConnections); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getMaxConnections) + .orElseGet(super::getMaxConnections); } - /* (non-Javadoc) */ @Override public int getMinConnections() { - return Optional.ofNullable(getDelegate()).map(Pool::getMinConnections).orElseGet(super::getMinConnections); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getMinConnections) + .orElseGet(super::getMinConnections); } - /* (non-Javadoc) */ @Override public boolean getMultiuserAuthentication() { - return Optional.ofNullable(getDelegate()).map(Pool::getMultiuserAuthentication) + + return Optional.ofNullable(getDelegate()) + .map(Pool::getMultiuserAuthentication) .orElseGet(super::getMultiuserAuthentication); } - /* (non-Javadoc) */ @Override public String getName() { - return Optional.ofNullable(getDelegate()).map(Pool::getName).orElseGet(super::getName); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getName) + .orElseGet(super::getName); } - /* (non-Javadoc) */ @Override public List getOnlineLocators() { - return Optional.ofNullable(getDelegate()).map(Pool::getOnlineLocators).orElseGet(super::getOnlineLocators); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getOnlineLocators) + .orElseGet(super::getOnlineLocators); } - /* (non-Javadoc) */ @Override public int getPendingEventCount() { - return Optional.ofNullable(getDelegate()).map(Pool::getPendingEventCount).orElse(0); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getPendingEventCount) + .orElse(0); } - /* (non-Javadoc) */ @Override public long getPingInterval() { - return Optional.ofNullable(getDelegate()).map(Pool::getPingInterval).orElseGet(super::getPingInterval); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getPingInterval) + .orElseGet(super::getPingInterval); } - /* (non-Javadoc) */ @Override public boolean getPRSingleHopEnabled() { - return Optional.ofNullable(getDelegate()).map(Pool::getPRSingleHopEnabled) + + return Optional.ofNullable(getDelegate()) + .map(Pool::getPRSingleHopEnabled) .orElseGet(super::getPRSingleHopEnabled); } - /* (non-Javadoc) */ @Override public QueryService getQueryService() { - return Optional.ofNullable(getDelegate()).map(Pool::getQueryService).orElseGet(super::getQueryService); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getQueryService) + .orElseGet(super::getQueryService); } - /* (non-Javadoc) */ @Override public int getReadTimeout() { - return Optional.ofNullable(getDelegate()).map(Pool::getReadTimeout).orElseGet(super::getReadTimeout); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getReadTimeout) + .orElseGet(super::getReadTimeout); } - /* (non-Javadoc) */ @Override public int getRetryAttempts() { - return Optional.ofNullable(getDelegate()).map(Pool::getRetryAttempts).orElseGet(super::getRetryAttempts); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getRetryAttempts) + .orElseGet(super::getRetryAttempts); } - /* (non-Javadoc) */ @Override public String getServerGroup() { - return Optional.ofNullable(getDelegate()).map(Pool::getServerGroup).orElseGet(super::getServerGroup); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getServerGroup) + .orElseGet(super::getServerGroup); } - /* (non-Javadoc) */ @Override public List getServers() { - return Optional.ofNullable(getDelegate()).map(Pool::getServers).orElseGet(super::getServers); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getServers) + .orElseGet(super::getServers); } - /* (non-Javadoc) */ @Override public int getSocketBufferSize() { - return Optional.ofNullable(getDelegate()).map(Pool::getSocketBufferSize).orElseGet(super::getSocketBufferSize); + + return Optional.ofNullable(getDelegate()) + .map(Pool::getSocketBufferSize) + .orElseGet(super::getSocketBufferSize); } - /* (non-Javadoc) */ @Override public int getSocketConnectTimeout() { - return Optional.ofNullable(getDelegate()).map(Pool::getSocketConnectTimeout) + + return Optional.ofNullable(getDelegate()) + .map(Pool::getSocketConnectTimeout) .orElseGet(super::getSocketConnectTimeout); } - /* (non-Javadoc) */ @Override public int getStatisticInterval() { - return Optional.ofNullable(getDelegate()).map(Pool::getStatisticInterval) + + return Optional.ofNullable(getDelegate()) + .map(Pool::getStatisticInterval) .orElseGet(super::getStatisticInterval); } - /* (non-Javadoc) */ @Override public int getSubscriptionAckInterval() { - return Optional.ofNullable(getDelegate()).map(Pool::getSubscriptionAckInterval) + + return Optional.ofNullable(getDelegate()) + .map(Pool::getSubscriptionAckInterval) .orElseGet(super::getSubscriptionAckInterval); } - /* (non-Javadoc) */ @Override public boolean getSubscriptionEnabled() { - return Optional.ofNullable(getDelegate()).map(Pool::getSubscriptionEnabled) + + return Optional.ofNullable(getDelegate()) + .map(Pool::getSubscriptionEnabled) .orElseGet(super::getSubscriptionEnabled); } - /* (non-Javadoc) */ @Override public int getSubscriptionMessageTrackingTimeout() { - return Optional.ofNullable(getDelegate()).map(Pool::getSubscriptionMessageTrackingTimeout) + + return Optional.ofNullable(getDelegate()) + .map(Pool::getSubscriptionMessageTrackingTimeout) .orElseGet(super::getSubscriptionMessageTrackingTimeout); } - /* (non-Javadoc) */ @Override public int getSubscriptionRedundancy() { - return Optional.ofNullable(getDelegate()).map(Pool::getSubscriptionRedundancy) + + return Optional.ofNullable(getDelegate()) + .map(Pool::getSubscriptionRedundancy) .orElseGet(super::getSubscriptionRedundancy); } - /* (non-Javadoc) */ @Override public boolean getThreadLocalConnections() { - return Optional.ofNullable(getDelegate()).map(Pool::getThreadLocalConnections) + + return Optional.ofNullable(getDelegate()) + .map(Pool::getThreadLocalConnections) .orElseGet(super::getThreadLocalConnections); } - /* (non-Javadoc) */ @Override public void destroy() { Optional.ofNullable(getDelegate()).ifPresent(Pool::destroy); } - /* (non-Javadoc) */ @Override public void destroy(boolean keepAlive) { Optional.ofNullable(getDelegate()).ifPresent(delegate -> delegate.destroy(keepAlive)); } - /* (non-Javadoc) */ @Override public void releaseThreadLocalConnection() { Optional.ofNullable(getDelegate()).ifPresent(Pool::releaseThreadLocalConnection); diff --git a/src/main/java/org/springframework/data/gemfire/client/support/FactoryDefaultsPoolAdapter.java b/src/main/java/org/springframework/data/gemfire/client/support/FactoryDefaultsPoolAdapter.java index 8ca4b20e..55aaf282 100644 --- a/src/main/java/org/springframework/data/gemfire/client/support/FactoryDefaultsPoolAdapter.java +++ b/src/main/java/org/springframework/data/gemfire/client/support/FactoryDefaultsPoolAdapter.java @@ -21,20 +21,21 @@ import java.net.InetSocketAddress; import java.util.Collections; import java.util.List; +import org.apache.geode.cache.client.Pool; import org.apache.geode.cache.client.PoolFactory; import org.apache.geode.cache.query.QueryService; import org.springframework.data.gemfire.GemfireUtils; import org.springframework.data.gemfire.client.PoolAdapter; /** - * FactoryDefaultsPoolAdapter is an abstract implementation of GemFire's {@link org.apache.geode.cache.client.Pool} - * interface and extension of {@link PoolAdapter} providing default factory values for all configuration properties + * {@link FactoryDefaultsPoolAdapter} is an abstract implementation of the {@link Pool} interface and extension of + * {@link PoolAdapter} that provides default factory values for all configuration properties * (e.g. freeConnectionTimeout, idleTimeout, etc). * * @author John Blum - * @see org.springframework.data.gemfire.client.PoolAdapter - * @see org.apache.geode.cache.client.PoolFactory * @see org.apache.geode.cache.client.Pool + * @see org.apache.geode.cache.client.PoolFactory + * @see org.springframework.data.gemfire.client.PoolAdapter * @since 1.8.0 */ @SuppressWarnings("unused") @@ -45,151 +46,126 @@ public abstract class FactoryDefaultsPoolAdapter extends PoolAdapter { protected static final String DEFAULT_POOL_NAME = "DEFAULT"; protected static final String LOCALHOST = "localhost"; - /* (non-Javadoc) */ @Override public int getFreeConnectionTimeout() { return PoolFactory.DEFAULT_FREE_CONNECTION_TIMEOUT; } - /* (non-Javadoc) */ @Override public long getIdleTimeout() { return PoolFactory.DEFAULT_IDLE_TIMEOUT; } - /* (non-Javadoc) */ @Override public int getLoadConditioningInterval() { return PoolFactory.DEFAULT_LOAD_CONDITIONING_INTERVAL; } - /* (non-Javadoc) */ @Override public List getLocators() { return Collections.emptyList(); } - /* (non-Javadoc) */ @Override public int getMaxConnections() { return PoolFactory.DEFAULT_MAX_CONNECTIONS; } - /* (non-Javadoc) */ @Override public int getMinConnections() { return PoolFactory.DEFAULT_MIN_CONNECTIONS; } - /* (non-Javadoc) */ @Override public boolean getMultiuserAuthentication() { return PoolFactory.DEFAULT_MULTIUSER_AUTHENTICATION; } - /* (non-Javadoc) */ @Override public String getName() { return DEFAULT_POOL_NAME; } - /* (non-Javadoc) */ @Override public List getOnlineLocators() { return Collections.emptyList(); } - /* (non-Javadoc) */ @Override public long getPingInterval() { return PoolFactory.DEFAULT_PING_INTERVAL; } - /* (non-Javadoc) */ @Override public boolean getPRSingleHopEnabled() { return PoolFactory.DEFAULT_PR_SINGLE_HOP_ENABLED; } - /* (non-Javadoc) */ @Override public QueryService getQueryService() { return null; } - /* (non-Javadoc) */ @Override public int getReadTimeout() { return PoolFactory.DEFAULT_READ_TIMEOUT; } - /* (non-Javadoc) */ @Override public int getRetryAttempts() { return PoolFactory.DEFAULT_RETRY_ATTEMPTS; } - /* (non-Javadoc) */ @Override public String getServerGroup() { return PoolFactory.DEFAULT_SERVER_GROUP; } - /* (non-Javadoc) */ @Override public List getServers() { return Collections.singletonList(new InetSocketAddress(LOCALHOST, GemfireUtils.DEFAULT_CACHE_SERVER_PORT)); } - /* (non-Javadoc) */ @Override public int getSocketBufferSize() { return PoolFactory.DEFAULT_SOCKET_BUFFER_SIZE; } - /* (non-Javadoc) */ @Override public int getSocketConnectTimeout() { return PoolFactory.DEFAULT_SOCKET_CONNECT_TIMEOUT; } - /* (non-Javadoc) */ @Override public int getStatisticInterval() { return PoolFactory.DEFAULT_STATISTIC_INTERVAL; } - /* (non-Javadoc) */ @Override public int getSubscriptionAckInterval() { return PoolFactory.DEFAULT_SUBSCRIPTION_ACK_INTERVAL; } - /* (non-Javadoc) */ @Override public boolean getSubscriptionEnabled() { return PoolFactory.DEFAULT_SUBSCRIPTION_ENABLED; } - /* (non-Javadoc) */ @Override public int getSubscriptionMessageTrackingTimeout() { return PoolFactory.DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT; } - /* (non-Javadoc) */ @Override public int getSubscriptionRedundancy() { return PoolFactory.DEFAULT_SUBSCRIPTION_REDUNDANCY; } - /* (non-Javadoc) */ @Override public boolean getThreadLocalConnections() { return PoolFactory.DEFAULT_THREAD_LOCAL_CONNECTIONS; } - /* (non-Javadoc) */ public void destroy() { destroy(DEFAULT_KEEP_ALIVE); } diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheConfiguration.java index aaa13d7b..fef76035 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheConfiguration.java @@ -71,7 +71,7 @@ import org.springframework.util.StringUtils; @SuppressWarnings("unused") public class ClientCacheConfiguration extends AbstractCacheConfiguration { - private static final AtomicBoolean CLIENT_REGION_POOL_BEAN_FACTORY_POST_PROCESSOR_REGISTERED = + private static final AtomicBoolean INFRASTRUCTURE_COMPONENTS_REGISTERED = new AtomicBoolean(false); protected static final boolean DEFAULT_READY_FOR_EVENTS = false; @@ -205,13 +205,18 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration { super.configureInfrastructure(importMetadata); - registerClientRegionPoolBeanFactoryPostProcessor(importMetadata); + registerInfrastructureComponents(importMetadata); } - /* (non-Javadoc) */ - private void registerClientRegionPoolBeanFactoryPostProcessor(AnnotationMetadata importMetadata) { + private void registerInfrastructureComponents(AnnotationMetadata importMetadata) { + + if (INFRASTRUCTURE_COMPONENTS_REGISTERED.compareAndSet(false, true)) { + + /* + register(BeanDefinitionBuilder.rootBeanDefinition(ClientCachePoolBeanFactoryPostProcessor.class) + .setRole(BeanDefinition.ROLE_INFRASTRUCTURE).getBeanDefinition()); + */ - if (CLIENT_REGION_POOL_BEAN_FACTORY_POST_PROCESSOR_REGISTERED.compareAndSet(false, true)) { register(BeanDefinitionBuilder.rootBeanDefinition(ClientRegionPoolBeanFactoryPostProcessor.class) .setRole(BeanDefinition.ROLE_INFRASTRUCTURE).getBeanDefinition()); } diff --git a/src/main/java/org/springframework/data/gemfire/config/support/AbstractDependencyStructuringBeanFactoryPostProcessor.java b/src/main/java/org/springframework/data/gemfire/config/support/AbstractDependencyStructuringBeanFactoryPostProcessor.java new file mode 100644 index 00000000..7b11f0be --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/support/AbstractDependencyStructuringBeanFactoryPostProcessor.java @@ -0,0 +1,65 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.config.support; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.data.gemfire.client.ClientCacheFactoryBean; +import org.springframework.data.gemfire.client.ClientRegionFactoryBean; +import org.springframework.data.gemfire.client.PoolFactoryBean; +import org.springframework.util.StringUtils; + +/** + * The AbstractDependencyStructuringBeanFactoryPostProcessor class... + * + * @author John Blum + * @since 1.0.0 + */ +@SuppressWarnings("unused") +public abstract class AbstractDependencyStructuringBeanFactoryPostProcessor implements BeanFactoryPostProcessor { + + protected boolean isBeanDefinitionOfType(BeanDefinition beanDefinition, Class type) { + + return Optional.of(beanDefinition) + .map(it -> beanDefinition.getBeanClassName()) + .filter(StringUtils::hasText) + .map(beanClassName -> type.getName().equals(beanClassName)) + .orElseGet(() -> + Optional.ofNullable(beanDefinition.getFactoryMethodName()) + .filter(StringUtils::hasText) + .filter(it -> beanDefinition instanceof AnnotatedBeanDefinition) + .map(it -> ((AnnotatedBeanDefinition) beanDefinition).getFactoryMethodMetadata()) + .map(methodMetadata -> type.getName().equals(methodMetadata.getReturnTypeName())) + .orElse(false) + ); + } + + protected boolean isClientCacheBean(BeanDefinition beanDefinition) { + return isBeanDefinitionOfType(beanDefinition, ClientCacheFactoryBean.class); + } + + protected boolean isClientRegionBean(BeanDefinition beanDefinition) { + return isBeanDefinitionOfType(beanDefinition, ClientRegionFactoryBean.class); + } + + protected boolean isPoolBean(BeanDefinition beanDefinition) { + return isBeanDefinitionOfType(beanDefinition, PoolFactoryBean.class); + } +} diff --git a/src/main/java/org/springframework/data/gemfire/config/support/ClientCachePoolBeanFactoryPostProcessor.java b/src/main/java/org/springframework/data/gemfire/config/support/ClientCachePoolBeanFactoryPostProcessor.java new file mode 100644 index 00000000..a6a3225f --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/support/ClientCachePoolBeanFactoryPostProcessor.java @@ -0,0 +1,47 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.config.support; + +import java.util.Arrays; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.data.gemfire.config.xml.GemfireConstants; +import org.springframework.data.gemfire.util.SpringUtils; + +/** + * The ClientCachePoolBeanFactoryPostProcessor class... + * + * @author John Blum + * @since 1.0.0 + */ +public class ClientCachePoolBeanFactoryPostProcessor extends AbstractDependencyStructuringBeanFactoryPostProcessor { + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + + Arrays.stream(beanFactory.getBeanDefinitionNames()).forEach(beanName -> { + + BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); + + if (isPoolBean(beanDefinition)) { + SpringUtils.addDependsOn(beanDefinition, GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME); + } + }); + } +} diff --git a/src/main/java/org/springframework/data/gemfire/config/support/ClientRegionPoolBeanFactoryPostProcessor.java b/src/main/java/org/springframework/data/gemfire/config/support/ClientRegionPoolBeanFactoryPostProcessor.java index d2bad814..f55c5e35 100644 --- a/src/main/java/org/springframework/data/gemfire/config/support/ClientRegionPoolBeanFactoryPostProcessor.java +++ b/src/main/java/org/springframework/data/gemfire/config/support/ClientRegionPoolBeanFactoryPostProcessor.java @@ -24,14 +24,10 @@ import java.util.Set; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValue; -import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.data.gemfire.client.ClientRegionFactoryBean; -import org.springframework.data.gemfire.client.PoolFactoryBean; import org.springframework.data.gemfire.util.SpringUtils; -import org.springframework.util.StringUtils; /** * {@link ClientRegionPoolBeanFactoryPostProcessor} is a Spring {@link BeanFactoryPostProcessor} implementation @@ -44,7 +40,7 @@ import org.springframework.util.StringUtils; * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor * @since 1.8.2 */ -public class ClientRegionPoolBeanFactoryPostProcessor implements BeanFactoryPostProcessor { +public class ClientRegionPoolBeanFactoryPostProcessor extends AbstractDependencyStructuringBeanFactoryPostProcessor { protected static final String POOL_NAME_PROPERTY = "poolName"; @@ -82,35 +78,11 @@ public class ClientRegionPoolBeanFactoryPostProcessor implements BeanFactoryPost }); } - boolean isBeanDefinitionOfType(BeanDefinition beanDefinition, Class type) { - - return Optional.of(beanDefinition) - .map(it -> beanDefinition.getBeanClassName()) - .filter(StringUtils::hasText) - .map(beanClassName -> type.getName().equals(beanClassName)) - .orElseGet(() -> - Optional.ofNullable(beanDefinition.getFactoryMethodName()) - .filter(StringUtils::hasText) - .filter(it -> beanDefinition instanceof AnnotatedBeanDefinition) - .map(it -> ((AnnotatedBeanDefinition) beanDefinition).getFactoryMethodMetadata()) - .map(methodMetadata -> type.getName().equals(methodMetadata.getReturnTypeName())) - .orElse(false) - ); - } - - /* (non-Javadoc)*/ - boolean isClientRegionBean(BeanDefinition beanDefinition) { - return isBeanDefinitionOfType(beanDefinition, ClientRegionFactoryBean.class); - } - - /* (non-Javadoc)*/ - boolean isPoolBean(BeanDefinition beanDefinition) { - return isBeanDefinitionOfType(beanDefinition, PoolFactoryBean.class); - } - - /* (non-Javadoc) */ String getPoolName(BeanDefinition clientRegionBean) { - PropertyValue poolNameProperty = clientRegionBean.getPropertyValues().getPropertyValue(POOL_NAME_PROPERTY); - return (poolNameProperty != null ? String.valueOf(poolNameProperty.getValue()) : null); + + return Optional.ofNullable(clientRegionBean.getPropertyValues().getPropertyValue(POOL_NAME_PROPERTY)) + .map(PropertyValue::getValue) + .map(String::valueOf) + .orElse(null); } } diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/AbstractRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/AbstractRegionParser.java index 5ec34b80..9e569bf5 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/AbstractRegionParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/AbstractRegionParser.java @@ -19,6 +19,7 @@ package org.springframework.data.gemfire.config.xml; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -66,7 +67,7 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { @Override protected String getParentName(Element element) { String regionTemplate = element.getAttribute("template"); - return (StringUtils.hasText(regionTemplate) ? regionTemplate : super.getParentName(element)); + return StringUtils.hasText(regionTemplate) ? regionTemplate : super.getParentName(element); } /* (non-Javadoc) */ @@ -167,14 +168,14 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { BeanDefinition templateRegionAttributes = getRegionAttributesBeanDefinition(templateRegion); if (templateRegionAttributes != null) { - // NOTE we only need to merge the parent RegionAttributes with this since the parent will have - // already merged it's parent's RegionAttributes and so on... + // NOTE we only need to merge the parent's RegionAttributes with this since the parent + // will have already merged its parent's RegionAttributes and so on... regionAttributesBuilder.getRawBeanDefinition().overrideFrom(templateRegionAttributes); } } else { parserContext.getReaderContext().error(String.format( - "The Region template [%1$s] must be 'defined before' the Region [%2$s] referring to the template!", + "The Region template [%1$s] must be defined before the Region [%2$s] referring to the template", regionTemplateName, resolveId(element, regionBuilder.getRawBeanDefinition(), parserContext)), element); } @@ -188,11 +189,13 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { Object regionAttributes = null; if (region.getPropertyValues().contains("attributes")) { - PropertyValue attributesProperty = region.getPropertyValues().getPropertyValue("attributes"); - regionAttributes = attributesProperty.getValue(); + regionAttributes = + Optional.ofNullable(region.getPropertyValues().getPropertyValue("attributes")) + .map(PropertyValue::getValue) + .orElse(null); } - return (regionAttributes instanceof BeanDefinition ? (BeanDefinition) regionAttributes : null); + return regionAttributes instanceof BeanDefinition ? (BeanDefinition) regionAttributes : null; } protected void parseCollectionOfCustomSubElements(Element element, ParserContext parserContext, diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/CacheParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/CacheParser.java index 613b0878..2bff6ffd 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/CacheParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/CacheParser.java @@ -17,6 +17,7 @@ package org.springframework.data.gemfire.config.xml; import java.util.List; +import java.util.Optional; import org.apache.geode.internal.datasource.ConfigProperty; import org.springframework.beans.factory.BeanDefinitionStoreException; @@ -46,8 +47,13 @@ import org.w3c.dom.NamedNodeMap; * @author Oliver Gierke * @author David Turanski * @author John Blum + * @see org.springframework.beans.factory.support.AbstractBeanDefinition + * @see org.springframework.beans.factory.support.BeanDefinitionBuilder + * @see org.springframework.beans.factory.support.BeanDefinitionRegistry * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser + * @see org.springframework.beans.factory.xml.ParserContext * @see org.springframework.data.gemfire.CacheFactoryBean + * @see org.w3c.dom.Element */ class CacheParser extends AbstractSingleBeanDefinitionParser { @@ -63,80 +69,79 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { * {@inheritDoc} */ @Override - protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder cacheBuilder) { - super.doParse(element, builder); + super.doParse(element, cacheBuilder); registerGemFireBeanFactoryPostProcessors(getRegistry(parserContext)); - ParsingUtils.setPropertyValue(element, builder, "cache-xml-location", "cacheXml"); - ParsingUtils.setPropertyReference(element, builder, "properties-ref", "properties"); - ParsingUtils.setPropertyValue(element, builder, "use-bean-factory-locator"); - ParsingUtils.setPropertyValue(element, builder, "close"); - ParsingUtils.setPropertyValue(element, builder, "copy-on-read"); - ParsingUtils.setPropertyValue(element, builder, "critical-heap-percentage"); - ParsingUtils.setPropertyValue(element, builder, "critical-off-heap-percentage"); - ParsingUtils.setPropertyValue(element, builder, "eviction-heap-percentage"); - ParsingUtils.setPropertyValue(element, builder, "eviction-off-heap-percentage"); - ParsingUtils.setPropertyValue(element, builder, "enable-auto-reconnect"); - ParsingUtils.setPropertyValue(element, builder, "lock-lease"); - ParsingUtils.setPropertyValue(element, builder, "lock-timeout"); - ParsingUtils.setPropertyValue(element, builder, "message-sync-interval"); - parsePdxDiskStore(element, parserContext, builder); - ParsingUtils.setPropertyValue(element, builder, "pdx-ignore-unread-fields"); - ParsingUtils.setPropertyValue(element, builder, "pdx-read-serialized"); - ParsingUtils.setPropertyValue(element, builder, "pdx-persistent"); - ParsingUtils.setPropertyReference(element, builder, "pdx-serializer-ref", "pdxSerializer"); - ParsingUtils.setPropertyValue(element, builder, "search-timeout"); - ParsingUtils.setPropertyValue(element, builder, "use-cluster-configuration"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "cache-xml-location", "cacheXml"); + ParsingUtils.setPropertyReference(element, cacheBuilder, "properties-ref", "properties"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "use-bean-factory-locator"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "close"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "copy-on-read"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "critical-heap-percentage"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "critical-off-heap-percentage"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "eviction-heap-percentage"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "eviction-off-heap-percentage"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "enable-auto-reconnect"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "lock-lease"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "lock-timeout"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "message-sync-interval"); + parsePdxDiskStore(element, parserContext, cacheBuilder); + ParsingUtils.setPropertyValue(element, cacheBuilder, "pdx-ignore-unread-fields"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "pdx-read-serialized"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "pdx-persistent"); + ParsingUtils.setPropertyReference(element, cacheBuilder, "pdx-serializer-ref", "pdxSerializer"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "search-timeout"); + ParsingUtils.setPropertyValue(element, cacheBuilder, "use-cluster-configuration"); List txListeners = DomUtils.getChildElementsByTagName(element, "transaction-listener"); if (!CollectionUtils.isEmpty(txListeners)) { - ManagedList transactionListeners = new ManagedList(); + + ManagedList transactionListeners = new ManagedList<>(); for (Element txListener : txListeners) { transactionListeners.add(ParsingUtils.parseRefOrNestedBeanDeclaration( - txListener, parserContext, builder)); + txListener, parserContext, cacheBuilder)); } - builder.addPropertyValue("transactionListeners", transactionListeners); + cacheBuilder.addPropertyValue("transactionListeners", transactionListeners); } Element txWriter = DomUtils.getChildElementByTagName(element, "transaction-writer"); if (txWriter != null) { - builder.addPropertyValue("transactionWriter", ParsingUtils.parseRefOrNestedBeanDeclaration( - txWriter, parserContext, builder)); + cacheBuilder.addPropertyValue("transactionWriter", + ParsingUtils.parseRefOrNestedBeanDeclaration(txWriter, parserContext, cacheBuilder)); } - Element gatewayConflictResolver = DomUtils.getChildElementByTagName(element, "gateway-conflict-resolver"); + Element gatewayConflictResolver = + DomUtils.getChildElementByTagName(element, "gateway-conflict-resolver"); if (gatewayConflictResolver != null) { ParsingUtils.throwExceptionWhenGemFireFeatureUnavailable(GemfireFeature.WAN, element.getLocalName(), "gateway-conflict-resolver", parserContext); - builder.addPropertyValue("gatewayConflictResolver", ParsingUtils.parseRefOrSingleNestedBeanDeclaration( - gatewayConflictResolver, parserContext, builder)); + cacheBuilder.addPropertyValue("gatewayConflictResolver", ParsingUtils.parseRefOrSingleNestedBeanDeclaration( + gatewayConflictResolver, parserContext, cacheBuilder)); } - parseDynamicRegionFactory(element, builder); - parseJndiBindings(element, builder); + parseDynamicRegionFactory(element, cacheBuilder); + parseJndiBindings(element, cacheBuilder); } - /* (non-Javadoc) */ protected BeanDefinitionRegistry getRegistry(ParserContext parserContext) { return parserContext.getRegistry(); } - /* (non-Javadoc) */ - void registerGemFireBeanFactoryPostProcessors(BeanDefinitionRegistry registry) { + private void registerGemFireBeanFactoryPostProcessors(BeanDefinitionRegistry registry) { BeanDefinitionReaderUtils.registerWithGeneratedName( BeanDefinitionBuilder.genericBeanDefinition(CustomEditorBeanFactoryPostProcessor.class) .getBeanDefinition(), registry); } - /* (non-Javadoc) */ private void parsePdxDiskStore(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { ParsingUtils.setPropertyValue(element, builder, "pdx-disk-store", "pdxDiskStoreName"); @@ -148,15 +153,15 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { } } - /* (non-Javadoc) */ - void registerPdxDiskStoreAwareBeanFactoryPostProcessor(BeanDefinitionRegistry registry, String pdxDiskStoreName) { + private void registerPdxDiskStoreAwareBeanFactoryPostProcessor(BeanDefinitionRegistry registry, + String pdxDiskStoreName) { BeanDefinitionReaderUtils.registerWithGeneratedName( createPdxDiskStoreAwareBeanFactoryPostProcessorBeanDefinition(pdxDiskStoreName), registry); } - /* (non-Javadoc) */ - private AbstractBeanDefinition createPdxDiskStoreAwareBeanFactoryPostProcessorBeanDefinition(String pdxDiskStoreName) { + private AbstractBeanDefinition createPdxDiskStoreAwareBeanFactoryPostProcessorBeanDefinition( + String pdxDiskStoreName) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(PdxDiskStoreAwareBeanFactoryPostProcessor.class); @@ -166,25 +171,26 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { return builder.getBeanDefinition(); } - /* (non-Javadoc) */ - private void parseDynamicRegionFactory(Element element, BeanDefinitionBuilder builder) { + private void parseDynamicRegionFactory(Element element, BeanDefinitionBuilder cacheBuilder) { - Element dynamicRegionFactory = DomUtils.getChildElementByTagName(element, "dynamic-region-factory"); + Element dynamicRegionFactory = + DomUtils.getChildElementByTagName(element, "dynamic-region-factory"); if (dynamicRegionFactory != null) { + BeanDefinitionBuilder dynamicRegionSupport = buildDynamicRegionSupport(dynamicRegionFactory); + postProcessDynamicRegionSupport(element, dynamicRegionSupport); - builder.addPropertyValue("dynamicRegionSupport", dynamicRegionSupport.getBeanDefinition()); + cacheBuilder.addPropertyValue("dynamicRegionSupport", dynamicRegionSupport.getBeanDefinition()); } } - /* (non-Javadoc) */ private BeanDefinitionBuilder buildDynamicRegionSupport(Element dynamicRegionFactory) { if (dynamicRegionFactory != null) { - BeanDefinitionBuilder dynamicRegionSupport = BeanDefinitionBuilder.genericBeanDefinition( - CacheFactoryBean.DynamicRegionSupport.class); + BeanDefinitionBuilder dynamicRegionSupport = + BeanDefinitionBuilder.genericBeanDefinition(CacheFactoryBean.DynamicRegionSupport.class); String diskDirectory = dynamicRegionFactory.getAttribute("disk-dir"); @@ -213,17 +219,15 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { /** * @param dynamicRegionSupport {@link BeanDefinitionBuilder} for <gfe:dynamic-region-factory> element. */ - protected void postProcessDynamicRegionSupport(Element element, BeanDefinitionBuilder dynamicRegionSupport) { - } + protected void postProcessDynamicRegionSupport(Element element, BeanDefinitionBuilder dynamicRegionSupport) { } - /* (non-Javadoc) */ - private void parseJndiBindings(Element element, BeanDefinitionBuilder builder) { + private void parseJndiBindings(Element element, BeanDefinitionBuilder cacheBuilder) { List jndiBindings = DomUtils.getChildElementsByTagName(element, "jndi-binding"); if (!CollectionUtils.isEmpty(jndiBindings)) { - ManagedList jndiDataSources = new ManagedList(jndiBindings.size()); + ManagedList jndiDataSources = new ManagedList<>(jndiBindings.size()); for (Element jndiBinding : jndiBindings) { @@ -233,7 +237,7 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { // NOTE 'jndi-name' and 'type' are required by the XSD so we should have at least 2 attributes. NamedNodeMap attributes = jndiBinding.getAttributes(); - ManagedMap jndiAttributes = new ManagedMap(attributes.getLength()); + ManagedMap jndiAttributes = new ManagedMap<>(attributes.getLength()); for (int index = 0, length = attributes.getLength(); index < length; index++) { Attr attribute = (Attr) attributes.item(index); @@ -245,9 +249,11 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { List jndiProps = DomUtils.getChildElementsByTagName(jndiBinding, "jndi-prop"); if (!CollectionUtils.isEmpty(jndiProps)) { - ManagedList props = new ManagedList(jndiProps.size()); + + ManagedList props = new ManagedList<>(jndiProps.size()); for (Element jndiProp : jndiProps) { + String key = jndiProp.getAttribute("key"); String type = jndiProp.getAttribute("type"); String value = jndiProp.getTextContent(); @@ -267,7 +273,7 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { jndiDataSources.add(jndiDataSource.getBeanDefinition()); } - builder.addPropertyValue("jndiDataSources", jndiDataSources); + cacheBuilder.addPropertyValue("jndiDataSources", jndiDataSources); } } @@ -278,11 +284,12 @@ class CacheParser extends AbstractSingleBeanDefinitionParser { protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException { - String name = super.resolveId(element, definition, parserContext); + String name = Optional.of(super.resolveId(element, definition, parserContext)) + .filter(StringUtils::hasText) + .map(StringUtils::trimWhitespace) + .orElse(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME); - if (!StringUtils.hasText(name)) { - name = GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME; - // Set Cache bean alias for backwards compatibility... + if (!"gemfire-cache".equals(name)) { parserContext.getRegistry().registerAlias(name, "gemfire-cache"); } diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/ClientCacheParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/ClientCacheParser.java index c7d20230..b4100b6b 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/ClientCacheParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/ClientCacheParser.java @@ -45,14 +45,15 @@ class ClientCacheParser extends CacheParser { * {@inheritDoc} */ @Override - protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - super.doParse(element, parserContext, builder); + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder clientCacheBuilder) { - ParsingUtils.setPropertyValue(element, builder, "durable-client-id"); - ParsingUtils.setPropertyValue(element, builder, "durable-client-timeout"); - ParsingUtils.setPropertyValue(element, builder, "keep-alive"); - ParsingUtils.setPropertyValue(element, builder, "pool-name"); - ParsingUtils.setPropertyValue(element, builder, "ready-for-events"); + super.doParse(element, parserContext, clientCacheBuilder); + + ParsingUtils.setPropertyValue(element, clientCacheBuilder, "durable-client-id"); + ParsingUtils.setPropertyValue(element, clientCacheBuilder, "durable-client-timeout"); + ParsingUtils.setPropertyValue(element, clientCacheBuilder, "keep-alive"); + ParsingUtils.setPropertyValue(element, clientCacheBuilder, "pool-name"); + ParsingUtils.setPropertyValue(element, clientCacheBuilder, "ready-for-events"); } /** diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/ClientRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/ClientRegionParser.java index 2bdd0bfe..54910828 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/ClientRegionParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/ClientRegionParser.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2010-2018 the original author or authors. +======= + * Copyright 2018 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,9 +80,9 @@ class ClientRegionParser extends AbstractRegionParser { parseDiskStoreAttribute(element, regionBuilder); - // Client RegionAttributes for overflow/eviction, expiration and statistics - BeanDefinitionBuilder regionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition( - RegionAttributesFactoryBean.class); + // Client RegionAttributes for Compression, Eviction, Expiration and Statistics + BeanDefinitionBuilder regionAttributesBuilder = + BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class); mergeRegionTemplateAttributes(element, parserContext, regionBuilder, regionAttributesBuilder); @@ -92,9 +96,10 @@ class ClientRegionParser extends AbstractRegionParser { List subElements = DomUtils.getChildElements(element); - ManagedList interests = new ManagedList(); + ManagedList interests = new ManagedList<>(); for (Element subElement : subElements) { + String subElementLocalName = subElement.getLocalName(); if ("cache-listener".equals(subElementLocalName)) { @@ -126,8 +131,8 @@ class ClientRegionParser extends AbstractRegionParser { } } - /* (non-Javadoc) */ private void parseDiskStoreAttribute(Element element, BeanDefinitionBuilder builder) { + String diskStoreRefAttribute = element.getAttribute("disk-store-ref"); if (StringUtils.hasText(diskStoreRefAttribute)) { @@ -136,28 +141,28 @@ class ClientRegionParser extends AbstractRegionParser { } } - /* (non-Javadoc) */ private void parseCommonInterestAttributes(Element element, BeanDefinitionBuilder builder) { + ParsingUtils.setPropertyValue(element, builder, "durable", "durable"); ParsingUtils.setPropertyValue(element, builder, "receive-values", "receiveValues"); ParsingUtils.setPropertyValue(element, builder, "result-policy", "policy"); } - /* (non-Javadoc) */ private Object parseKeyInterest(Element keyInterestElement, ParserContext parserContext) { + BeanDefinitionBuilder keyInterestBuilder = BeanDefinitionBuilder.genericBeanDefinition(KeyInterest.class); - keyInterestBuilder.addConstructorArgValue(ParsingUtils.parseRefOrNestedBeanDeclaration(keyInterestElement, - parserContext, - keyInterestBuilder, "key-ref")); + keyInterestBuilder.addConstructorArgValue( + ParsingUtils.parseRefOrNestedBeanDeclaration(keyInterestElement, parserContext, keyInterestBuilder, + "key-ref")); parseCommonInterestAttributes(keyInterestElement, keyInterestBuilder); return keyInterestBuilder.getBeanDefinition(); } - /* (non-Javadoc) */ private Object parseRegexInterest(Element regexInterestElement) { + BeanDefinitionBuilder regexInterestBuilder = BeanDefinitionBuilder.genericBeanDefinition(RegexInterest.class); regexInterestBuilder.addConstructorArgValue(regexInterestElement.getAttribute("pattern")); diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/GemfireDataNamespaceHandler.java b/src/main/java/org/springframework/data/gemfire/config/xml/GemfireDataNamespaceHandler.java index 49cfcc68..62d4306f 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/GemfireDataNamespaceHandler.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/GemfireDataNamespaceHandler.java @@ -39,7 +39,9 @@ class GemfireDataNamespaceHandler extends NamespaceHandlerSupport { */ @Override public void init() { + RepositoryConfigurationExtension extension = new GemfireRepositoryConfigurationExtension(); + registerBeanDefinitionParser("datasource", new GemfireDataSourceParser()); registerBeanDefinitionParser("function-executions", new FunctionExecutionBeanDefinitionParser()); registerBeanDefinitionParser("json-region-autoproxy", new GemfireRegionAutoProxyParser()); diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/GemfireDataSourceParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/GemfireDataSourceParser.java index c1998773..5f75dc76 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/GemfireDataSourceParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/GemfireDataSourceParser.java @@ -13,8 +13,8 @@ package org.springframework.data.gemfire.config.xml; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; @@ -40,17 +40,35 @@ class GemfireDataSourceParser extends AbstractBeanDefinitionParser { static final String SUBSCRIPTION_ENABLED_ATTRIBUTE_NAME = "subscription-enabled"; static final String SUBSCRIPTION_ENABLED_PROPERTY_NAME = "subscriptionEnabled"; - protected final Log log = LogFactory.getLog(getClass()); + protected final Logger logger = LoggerFactory.getLogger(getClass()); /** * {@inheritDoc} */ @Override protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { + + parseAndRegisterClientCache(element, parserContext); + parseAndRegisterPool(element, parserContext); + registerGemFireDataSourcePostProcessor(parserContext); + + return null; + } + + private void parseAndRegisterClientCache(Element element, ParserContext parserContext) { + BeanDefinition clientCacheDefinition = new ClientCacheParser().parse(element, parserContext); - parserContext.getRegistry().registerBeanDefinition(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME, - clientCacheDefinition); + parserContext.getRegistry() + .registerBeanDefinition(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME, clientCacheDefinition); + + if (logger.isDebugEnabled()) { + logger.debug(String.format("Registered GemFire ClientCache bean [%1$s] of type [%2$s]%n", + GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME, clientCacheDefinition.getBeanClassName())); + } + } + + private void parseAndRegisterPool(Element element, ParserContext parserContext) { BeanDefinition poolDefinition = new PoolParser().parse(element, parserContext); @@ -61,19 +79,15 @@ class GemfireDataSourceParser extends AbstractBeanDefinitionParser { } parserContext.getRegistry().registerBeanDefinition(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, poolDefinition); + } - if (log.isDebugEnabled()) { - log.debug(String.format("Registered GemFire ClientCache bean [%1$s] of type [%2$s]%n", - GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME, clientCacheDefinition.getBeanClassName())); - } + private void registerGemFireDataSourcePostProcessor(ParserContext parserContext) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( - GemfireDataSourcePostProcessor.class); + BeanDefinitionBuilder builder = + BeanDefinitionBuilder.genericBeanDefinition(GemfireDataSourcePostProcessor.class); builder.addConstructorArgReference(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME); BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), parserContext.getRegistry()); - - return null; } } diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/ParsingUtils.java b/src/main/java/org/springframework/data/gemfire/config/xml/ParsingUtils.java index bc354c90..205a24a2 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/ParsingUtils.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/ParsingUtils.java @@ -92,6 +92,7 @@ abstract class ParsingUtils { static void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attributeName, String propertyName) { + setPropertyValue(element, builder, attributeName, propertyName, null); } @@ -333,7 +334,7 @@ abstract class ParsingUtils { @SuppressWarnings("unused") static void parseOptionalRegionAttributes(Element element, ParserContext parserContext, - BeanDefinitionBuilder regionAttributesBuilder) { + BeanDefinitionBuilder regionAttributesBuilder) { setPropertyValue(element, regionAttributesBuilder, "cloning-enabled"); setPropertyValue(element, regionAttributesBuilder, "concurrency-level"); diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/PoolParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/PoolParser.java index 03848b94..9c21b063 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/PoolParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/PoolParser.java @@ -66,17 +66,22 @@ class PoolParser extends AbstractSingleBeanDefinitionParser { static final String SERVER_ELEMENT_NAME = "server"; static final String SERVERS_ATTRIBUTE_NAME = "servers"; - /* (non-Javadoc) */ private static void registerInfrastructureComponents(ParserContext parserContext) { if (INFRASTRUCTURE_COMPONENTS_REGISTERED.compareAndSet(false, true)) { - AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder - .rootBeanDefinition(ClientRegionPoolBeanFactoryPostProcessor.class) + // Be careful to not to register this infrastructure component (just yet; requires more thought) + /* + BeanDefinitionReaderUtils.registerWithGeneratedName( + BeanDefinitionBuilder.rootBeanDefinition(ClientCachePoolBeanFactoryPostProcessor.class) .setRole(BeanDefinition.ROLE_INFRASTRUCTURE) - .getBeanDefinition(); + .getBeanDefinition(), parserContext.getRegistry()); + */ - BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, parserContext.getRegistry()); + BeanDefinitionReaderUtils.registerWithGeneratedName( + BeanDefinitionBuilder.rootBeanDefinition(ClientRegionPoolBeanFactoryPostProcessor.class) + .setRole(BeanDefinition.ROLE_INFRASTRUCTURE) + .getBeanDefinition(), parserContext.getRegistry()); } } @@ -92,30 +97,33 @@ class PoolParser extends AbstractSingleBeanDefinitionParser { * {@inheritDoc} */ @Override - protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder poolBuilder) { registerInfrastructureComponents(parserContext); - ParsingUtils.setPropertyValue(element, builder, "free-connection-timeout"); - ParsingUtils.setPropertyValue(element, builder, "idle-timeout"); - ParsingUtils.setPropertyValue(element, builder, "keep-alive"); - ParsingUtils.setPropertyValue(element, builder, "load-conditioning-interval"); - ParsingUtils.setPropertyValue(element, builder, "max-connections"); - ParsingUtils.setPropertyValue(element, builder, "min-connections"); - ParsingUtils.setPropertyValue(element, builder, "multi-user-authentication"); - ParsingUtils.setPropertyValue(element, builder, "ping-interval"); - ParsingUtils.setPropertyValue(element, builder, "pr-single-hop-enabled"); - ParsingUtils.setPropertyValue(element, builder, "read-timeout"); - ParsingUtils.setPropertyValue(element, builder, "retry-attempts"); - ParsingUtils.setPropertyValue(element, builder, "server-group"); - ParsingUtils.setPropertyValue(element, builder, "socket-buffer-size"); - ParsingUtils.setPropertyValue(element, builder, "socket-connect-timeout"); - ParsingUtils.setPropertyValue(element, builder, "statistic-interval"); - ParsingUtils.setPropertyValue(element, builder, "subscription-ack-interval"); - ParsingUtils.setPropertyValue(element, builder, "subscription-enabled"); - ParsingUtils.setPropertyValue(element, builder, "subscription-message-tracking-timeout"); - ParsingUtils.setPropertyValue(element, builder, "subscription-redundancy"); - ParsingUtils.setPropertyValue(element, builder, "thread-local-connections"); + // Be careful not to enable this dependency + //poolBuilder.addDependsOn(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME); + + ParsingUtils.setPropertyValue(element, poolBuilder, "free-connection-timeout"); + ParsingUtils.setPropertyValue(element, poolBuilder, "idle-timeout"); + ParsingUtils.setPropertyValue(element, poolBuilder, "keep-alive"); + ParsingUtils.setPropertyValue(element, poolBuilder, "load-conditioning-interval"); + ParsingUtils.setPropertyValue(element, poolBuilder, "max-connections"); + ParsingUtils.setPropertyValue(element, poolBuilder, "min-connections"); + ParsingUtils.setPropertyValue(element, poolBuilder, "multi-user-authentication"); + ParsingUtils.setPropertyValue(element, poolBuilder, "ping-interval"); + ParsingUtils.setPropertyValue(element, poolBuilder, "pr-single-hop-enabled"); + ParsingUtils.setPropertyValue(element, poolBuilder, "read-timeout"); + ParsingUtils.setPropertyValue(element, poolBuilder, "retry-attempts"); + ParsingUtils.setPropertyValue(element, poolBuilder, "server-group"); + ParsingUtils.setPropertyValue(element, poolBuilder, "socket-buffer-size"); + ParsingUtils.setPropertyValue(element, poolBuilder, "socket-connect-timeout"); + ParsingUtils.setPropertyValue(element, poolBuilder, "statistic-interval"); + ParsingUtils.setPropertyValue(element, poolBuilder, "subscription-ack-interval"); + ParsingUtils.setPropertyValue(element, poolBuilder, "subscription-enabled"); + ParsingUtils.setPropertyValue(element, poolBuilder, "subscription-message-tracking-timeout"); + ParsingUtils.setPropertyValue(element, poolBuilder, "subscription-redundancy"); + ParsingUtils.setPropertyValue(element, poolBuilder, "thread-local-connections"); List childElements = DomUtils.getChildElements(element); @@ -137,8 +145,8 @@ class PoolParser extends AbstractSingleBeanDefinitionParser { BeanDefinitionRegistry registry = resolveRegistry(parserContext); - boolean locatorsSet = parseLocators(element, builder, registry); - boolean serversSet = parseServers(element, builder, registry); + boolean locatorsSet = parseLocators(element, poolBuilder, registry); + boolean serversSet = parseServers(element, poolBuilder, registry); // If neither Locators nor Servers were explicitly configured, then setup a connection to a CacheServer // running on localhost, listening on the default CacheServer port, 40404 @@ -147,20 +155,18 @@ class PoolParser extends AbstractSingleBeanDefinitionParser { } if (!locators.isEmpty()) { - builder.addPropertyValue("locators", locators); + poolBuilder.addPropertyValue("locators", locators); } if (!servers.isEmpty()) { - builder.addPropertyValue("servers", servers); + poolBuilder.addPropertyValue("servers", servers); } } - /* (non-Javadoc) */ BeanDefinitionRegistry resolveRegistry(ParserContext parserContext) { return parserContext.getRegistry(); } - /* (non-Javadoc) */ BeanDefinition buildConnection(String host, String port, boolean server) { BeanDefinitionBuilder connectionEndpointBuilder = @@ -172,7 +178,6 @@ class PoolParser extends AbstractSingleBeanDefinitionParser { return connectionEndpointBuilder.getBeanDefinition(); } - /* (non-Javadoc) */ BeanDefinition buildConnections(String expression, boolean server) { BeanDefinitionBuilder connectionEndpointListBuilder = @@ -185,27 +190,23 @@ class PoolParser extends AbstractSingleBeanDefinitionParser { return connectionEndpointListBuilder.getBeanDefinition(); } - /* (non-Javadoc) */ String defaultHost(String host) { return (StringUtils.hasText(host) ? host : DEFAULT_HOST); } - /* (non-Javadoc) */ String defaultPort(String port, boolean server) { return (StringUtils.hasText(port) ? port : (server ? String.valueOf(DEFAULT_SERVER_PORT) : String.valueOf(DEFAULT_LOCATOR_PORT))); } - /* (non-Javadoc) */ BeanDefinition parseLocator(Element element) { return buildConnection(element.getAttribute(HOST_ATTRIBUTE_NAME), element.getAttribute(PORT_ATTRIBUTE_NAME), false); } - /* (non-Javadoc) */ boolean parseLocators(Element element, BeanDefinitionBuilder poolBuilder, BeanDefinitionRegistry registry) { String locatorsAttributeValue = element.getAttribute(LOCATORS_ATTRIBUTE_NAME); @@ -232,14 +233,12 @@ class PoolParser extends AbstractSingleBeanDefinitionParser { return false; } - /* (non-Javadoc) */ BeanDefinition parseServer(Element element) { return buildConnection(element.getAttribute(HOST_ATTRIBUTE_NAME), element.getAttribute(PORT_ATTRIBUTE_NAME), true); } - /* (non-Javadoc) */ boolean parseServers(Element element, BeanDefinitionBuilder poolBuilder, BeanDefinitionRegistry registry) { String serversAttributeValue = element.getAttribute(SERVERS_ATTRIBUTE_NAME); @@ -266,19 +265,16 @@ class PoolParser extends AbstractSingleBeanDefinitionParser { return false; } - /* (non-Javadoc) */ String resolveId(Element element) { return Optional.ofNullable(element.getAttribute(ID_ATTRIBUTE)).filter(StringUtils::hasText) .orElse(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME); } - /* (non-Javadoc) */ String resolveDereferencedId(Element element) { return SpringUtils.dereferenceBean(resolveId(element)); } - /* (non-Javadoc) */ @Override protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException { diff --git a/src/main/java/org/springframework/data/gemfire/function/config/AbstractFunctionExecutionBeanDefinitionBuilder.java b/src/main/java/org/springframework/data/gemfire/function/config/AbstractFunctionExecutionBeanDefinitionBuilder.java index 62091142..7812953f 100644 --- a/src/main/java/org/springframework/data/gemfire/function/config/AbstractFunctionExecutionBeanDefinitionBuilder.java +++ b/src/main/java/org/springframework/data/gemfire/function/config/AbstractFunctionExecutionBeanDefinitionBuilder.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2002-2018 the original author or authors. +======= + * Copyright 2002-2013 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -34,37 +38,32 @@ abstract class AbstractFunctionExecutionBeanDefinitionBuilder { protected final Log log = LogFactory.getLog(getClass()); - /** - * - * @param configuration the configuration values - */ AbstractFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) { - Assert.notNull(configuration); + + Assert.notNull(configuration, "FunctionExecutionConfiguration must not be null"); + this.configuration = configuration; } - /** - * Build the bean definition - * @param registry - * @return - */ BeanDefinition build(BeanDefinitionRegistry registry) { - BeanDefinitionBuilder functionProxyFactoryBeanBuilder = BeanDefinitionBuilder.rootBeanDefinition( - getFunctionProxyFactoryBeanClass()); - functionProxyFactoryBeanBuilder.addConstructorArgValue(configuration.getFunctionExecutionInterface()); - functionProxyFactoryBeanBuilder.addConstructorArgReference(BeanDefinitionReaderUtils.registerWithGeneratedName( - buildGemfireFunctionOperations(registry), registry)); + BeanDefinitionBuilder functionProxyFactoryBeanBuilder = + BeanDefinitionBuilder.rootBeanDefinition(getFunctionProxyFactoryBeanClass()); + + functionProxyFactoryBeanBuilder.addConstructorArgValue(this.configuration.getFunctionExecutionInterface()); + functionProxyFactoryBeanBuilder.addConstructorArgReference(BeanDefinitionReaderUtils + .registerWithGeneratedName(buildGemfireFunctionOperations(registry), registry)); return functionProxyFactoryBeanBuilder.getBeanDefinition(); } protected AbstractBeanDefinition buildGemfireFunctionOperations(BeanDefinitionRegistry registry) { + BeanDefinitionBuilder functionTemplateBuilder = getGemfireFunctionOperationsBeanDefinitionBuilder(registry); functionTemplateBuilder.setLazyInit(true); - String resultCollectorReference = (String) configuration.getAttribute("resultCollector"); + String resultCollectorReference = (String) this.configuration.getAttribute("resultCollector"); if (StringUtils.hasText(resultCollectorReference)){ functionTemplateBuilder.addPropertyReference("resultCollector", resultCollectorReference); @@ -73,10 +72,8 @@ abstract class AbstractFunctionExecutionBeanDefinitionBuilder { return functionTemplateBuilder.getBeanDefinition(); } - /* Subclasses implement to specify the types to uses. */ protected abstract Class getFunctionProxyFactoryBeanClass(); - protected abstract BeanDefinitionBuilder getGemfireFunctionOperationsBeanDefinitionBuilder( - BeanDefinitionRegistry registry); + protected abstract BeanDefinitionBuilder getGemfireFunctionOperationsBeanDefinitionBuilder(BeanDefinitionRegistry registry); } diff --git a/src/main/java/org/springframework/data/gemfire/function/config/AbstractFunctionExecutionConfigurationSource.java b/src/main/java/org/springframework/data/gemfire/function/config/AbstractFunctionExecutionConfigurationSource.java index 7bb52b73..66637cc4 100644 --- a/src/main/java/org/springframework/data/gemfire/function/config/AbstractFunctionExecutionConfigurationSource.java +++ b/src/main/java/org/springframework/data/gemfire/function/config/AbstractFunctionExecutionConfigurationSource.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2002-2018 the original author or authors. +======= + * Copyright 2002-2013 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -12,19 +16,21 @@ */ package org.springframework.data.gemfire.function.config; +import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeIterable; + import java.lang.annotation.Annotation; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.ScannedGenericBeanDefinition; import org.springframework.core.io.ResourceLoader; -import org.springframework.core.type.filter.TypeFilter; import org.springframework.data.gemfire.function.annotation.OnMember; import org.springframework.data.gemfire.function.annotation.OnMembers; import org.springframework.data.gemfire.function.annotation.OnRegion; @@ -32,68 +38,68 @@ import org.springframework.data.gemfire.function.annotation.OnServer; import org.springframework.data.gemfire.function.annotation.OnServers; /** +<<<<<<< Updated upstream * Annotation based configuration source for function executions * * @author David Turanski +======= + * Abstract base class and configuration source for Function Executions. +>>>>>>> Stashed changes * + * @author David Turanski + * @author John Blum + * @see org.springframework.data.gemfire.function.config.FunctionExecutionConfiguration */ abstract class AbstractFunctionExecutionConfigurationSource implements FunctionExecutionConfigurationSource { private static Set> functionExecutionAnnotationTypes; static { - Set> annotationTypes = new HashSet>(5); + Set> annotationTypes = new HashSet<>(5); + + annotationTypes.add(OnMember.class); + annotationTypes.add(OnMembers.class); annotationTypes.add(OnRegion.class); annotationTypes.add(OnServer.class); annotationTypes.add(OnServers.class); - annotationTypes.add(OnMember.class); - annotationTypes.add(OnMembers.class); functionExecutionAnnotationTypes = Collections.unmodifiableSet(annotationTypes); } - protected Log logger = LogFactory.getLog(getClass()); - static Set> getFunctionExecutionAnnotationTypes() { return functionExecutionAnnotationTypes; } static Set getFunctionExecutionAnnotationTypeNames() { - Set functionExecutionTypeNames = new HashSet(getFunctionExecutionAnnotationTypes().size()); - - for (Class annotationType : getFunctionExecutionAnnotationTypes()) { - functionExecutionTypeNames.add(annotationType.getName()); - } - - return functionExecutionTypeNames; + return getFunctionExecutionAnnotationTypes().stream().map(Class::getName).collect(Collectors.toSet()); } + protected Log logger = LogFactory.getLog(getClass()); + public Collection getCandidates(ResourceLoader loader) { - ClassPathScanningCandidateComponentProvider scanner = new FunctionExecutionComponentProvider( - getIncludeFilters(), getFunctionExecutionAnnotationTypes()); + + ClassPathScanningCandidateComponentProvider scanner = + new FunctionExecutionComponentProvider(getIncludeFilters(), getFunctionExecutionAnnotationTypes()); scanner.setResourceLoader(loader); - for (TypeFilter filter : getExcludeFilters()) { - scanner.addExcludeFilter(filter); - } + StreamSupport.stream(nullSafeIterable(getExcludeFilters()).spliterator(), false) + .forEach(scanner::addExcludeFilter); - Set result = new HashSet(); + Set result = new HashSet<>(); for (String basePackage : getBasePackages()) { + if (logger.isDebugEnabled()) { logger.debug("scanning package " + basePackage); } - Collection candidateComponents = scanner.findCandidateComponents(basePackage); - - for (BeanDefinition beanDefinition : candidateComponents) { - result.add((ScannedGenericBeanDefinition) beanDefinition); - } + scanner.findCandidateComponents(basePackage).stream() + .map(beanDefinition -> (ScannedGenericBeanDefinition) beanDefinition) + .forEach(result::add); } return result; } - } diff --git a/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionBuilderFactory.java b/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionBuilderFactory.java index 75dc4cd4..e25a84e4 100644 --- a/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionBuilderFactory.java +++ b/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionBuilderFactory.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2002-2018 the original author or authors. +======= + * Copyright 2002-2013 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -37,6 +41,7 @@ import org.springframework.data.gemfire.function.annotation.OnServers; abstract class FunctionExecutionBeanDefinitionBuilderFactory { static AbstractFunctionExecutionBeanDefinitionBuilder newInstance(FunctionExecutionConfiguration configuration) { + String functionExecutionAnnotation = configuration.getAnnotationType(); if (OnMember.class.getName().equals(functionExecutionAnnotation)) { @@ -57,5 +62,4 @@ abstract class FunctionExecutionBeanDefinitionBuilderFactory { return null; } - } diff --git a/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionParser.java b/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionParser.java index ba6606fa..9ad79c20 100644 --- a/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionParser.java +++ b/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionParser.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2002-2018 the original author or authors. +======= + * Copyright 2002-2013 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -18,28 +22,24 @@ import org.springframework.beans.factory.xml.ParserContext; import org.w3c.dom.Element; /** - * Parse for <function-executions> definitions. + * Parser for a <function-executions> bean definition. * * @author David Turanski * @author John Blum * @see org.springframework.beans.factory.config.BeanDefinition * @see org.springframework.beans.factory.xml.BeanDefinitionParser * @see org.springframework.beans.factory.xml.ParserContext + * @see org.w3c.dom.Element */ public class FunctionExecutionBeanDefinitionParser implements BeanDefinitionParser { - /* (non-Javadoc) + /* + * (non-Javadoc) * @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext) */ @Override public BeanDefinition parse(Element element, ParserContext parserContext) { - - AbstractFunctionExecutionConfigurationSource configurationSource = new XmlFunctionExecutionConfigurationSource( - element, parserContext); - - new FunctionExecutionBeanDefinitionRegistrar().registerBeanDefinitions(configurationSource, parserContext.getRegistry()); - + new FunctionExecutionBeanDefinitionRegistrar().registerBeanDefinitions(element, parserContext); return null; } - } diff --git a/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionRegistrar.java b/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionRegistrar.java index 4436d575..317d224f 100644 --- a/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionRegistrar.java +++ b/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionBeanDefinitionRegistrar.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2002-2018 the original author or authors. +======= + * Copyright 2002-2013 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -10,59 +14,81 @@ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ + package org.springframework.data.gemfire.function.config; +import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException; + +import java.util.Optional; import java.util.Set; import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.xml.ParserContext; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.context.annotation.ScannedGenericBeanDefinition; +import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.type.AnnotationMetadata; import org.springframework.util.Assert; import org.springframework.util.StringUtils; +import org.w3c.dom.Element; /** * {@link ImportBeanDefinitionRegistrar} for {code} @EnableGemfireFunctionExecutions {code} * Scans for interfaces annotated with one of {code} @OnRegion, @OnServer, @OnServers, @OnMember, @OnMembers {code} - * @author David Turanski * + * @author David Turanski + * @author John Blum */ class FunctionExecutionBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { - /* (non-Javadoc) - * @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry) + /* + * (non-Javadoc) + * @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar + * #registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry) */ @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) { - AbstractFunctionExecutionConfigurationSource configurationSource = new AnnotationFunctionExecutionConfigurationSource( - annotationMetadata); + + AbstractFunctionExecutionConfigurationSource configurationSource = + new AnnotationFunctionExecutionConfigurationSource(annotationMetadata); registerBeanDefinitions(configurationSource, registry); } - /* - * This registers bean definitions from any function execution configuration source + void registerBeanDefinitions(Element element, ParserContext parserContext) { + + AbstractFunctionExecutionConfigurationSource configurationSource = + new XmlFunctionExecutionConfigurationSource(element, parserContext); + + registerBeanDefinitions(configurationSource, parserContext.getRegistry()); + } + + /** + * Registers bean definitions from any {@link FunctionExecutionConfigurationSource}. */ void registerBeanDefinitions(AbstractFunctionExecutionConfigurationSource functionExecutionConfigurationSource, BeanDefinitionRegistry registry) { - for (ScannedGenericBeanDefinition beanDefinition : functionExecutionConfigurationSource.getCandidates( - new DefaultResourceLoader())) { + Set functionExecutionAnnotationTypeNames = + AbstractFunctionExecutionConfigurationSource.getFunctionExecutionAnnotationTypeNames(); - String functionExecutionAnnotation = getFunctionExecutionAnnotation(beanDefinition, - AnnotationFunctionExecutionConfigurationSource.getFunctionExecutionAnnotationTypeNames()); + for (ScannedGenericBeanDefinition beanDefinition : functionExecutionConfigurationSource + .getCandidates(new DefaultResourceLoader())) { - Assert.notNull(functionExecutionAnnotation); + String functionExecutionAnnotation = + Optional.ofNullable(getFunctionExecutionAnnotation(beanDefinition, functionExecutionAnnotationTypeNames)) + .orElseThrow(() -> newIllegalStateException(String.format("No Function Execution Annotation [%1$s] found for type [%2$s]", + functionExecutionAnnotationTypeNames, beanDefinition.getBeanClassName()))); - String beanName = (String) beanDefinition.getMetadata().getAnnotationAttributes( - functionExecutionAnnotation).get("id"); - - if (!StringUtils.hasText(beanName)) { - beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, registry); - } + String beanName = Optional.of(beanDefinition.getMetadata()) + .map(annotationMetadata -> annotationMetadata.getAnnotationAttributes(functionExecutionAnnotation)) + .map(AnnotationAttributes::fromMap) + .map(annotationAttributes -> annotationAttributes.getString("id")) + .filter(StringUtils::hasText) + .orElseGet(() -> BeanDefinitionReaderUtils.generateBeanName(beanDefinition, registry)); AbstractFunctionExecutionBeanDefinitionBuilder builder = FunctionExecutionBeanDefinitionBuilderFactory .newInstance(new FunctionExecutionConfiguration(beanDefinition, functionExecutionAnnotation)); @@ -74,20 +100,19 @@ class FunctionExecutionBeanDefinitionRegistrar implements ImportBeanDefinitionRe private String getFunctionExecutionAnnotation(ScannedGenericBeanDefinition beanDefinition, Set functionExecutionAnnotationTypeNames) { - Set annotationTypes = beanDefinition.getMetadata().getAnnotationTypes(); + String existingFunctionExecutionAnnotation = null; - String functionExecutionAnnotation = null; - - for (String annotationType : annotationTypes) { + for (String annotationType : beanDefinition.getMetadata().getAnnotationTypes()) { if (functionExecutionAnnotationTypeNames.contains(annotationType)) { - Assert.isNull(functionExecutionAnnotation, String.format( - "interface %1$s contains multiple Function Execution Annotations: %2$s, %3$s", - beanDefinition.getBeanClassName(), functionExecutionAnnotation, annotationType)); - functionExecutionAnnotation = annotationType; + + Assert.isNull(existingFunctionExecutionAnnotation, + String.format("interface [%1$s] contains multiple Function Execution Annotations: %2$s, %3$s", + beanDefinition.getBeanClassName(), existingFunctionExecutionAnnotation, annotationType)); + + existingFunctionExecutionAnnotation = annotationType; } } - return functionExecutionAnnotation; + return existingFunctionExecutionAnnotation; } - } diff --git a/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionConfiguration.java b/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionConfiguration.java index 31682b65..825a7a39 100644 --- a/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionConfiguration.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2002-2018 the original author or authors. +======= + * Copyright 2002-2013 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -15,6 +19,7 @@ package org.springframework.data.gemfire.function.config; import java.util.Map; import org.springframework.context.annotation.ScannedGenericBeanDefinition; +import org.springframework.data.gemfire.util.SpringUtils; import org.springframework.util.Assert; /** @@ -27,29 +32,29 @@ class FunctionExecutionConfiguration { private Class functionExecutionInterface; - private final Map attributes; + private final Map annotationAttributes; private final String annotationType; /* constructor for testing purposes only! */ FunctionExecutionConfiguration() { this.annotationType = null; - this.attributes = null; + this.annotationAttributes = null; } FunctionExecutionConfiguration(ScannedGenericBeanDefinition beanDefinition, String annotationType) { + try { this.annotationType = annotationType; - this.attributes = beanDefinition.getMetadata().getAnnotationAttributes(annotationType, true); + this.annotationAttributes = beanDefinition.getMetadata().getAnnotationAttributes(annotationType, true); this.functionExecutionInterface = beanDefinition.resolveBeanClass(beanDefinition.getClass().getClassLoader()); - Assert.isTrue(functionExecutionInterface.isInterface(), - String.format("The annotation %1$s only applies to an interface. It is not valid for the type %2$s", - annotationType, functionExecutionInterface.getName())); - + Assert.isTrue(this.functionExecutionInterface != null && this.functionExecutionInterface.isInterface(), + String.format("The annotation %1$s only applies to an interface. It is not valid for type %2$s", + annotationType, SpringUtils.nullSafeName(this.functionExecutionInterface))); } - catch (ClassNotFoundException e) { - throw new RuntimeException(e); + catch (ClassNotFoundException cause) { + throw new RuntimeException(cause); } } @@ -58,15 +63,14 @@ class FunctionExecutionConfiguration { } Object getAttribute(String name) { - return attributes.get(name); + return this.annotationAttributes.get(name); } Map getAttributes() { - return this.attributes; + return this.annotationAttributes; } Class getFunctionExecutionInterface() { return this.functionExecutionInterface; } - } diff --git a/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionConfigurationSource.java b/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionConfigurationSource.java index 0919d3ed..a89bba95 100644 --- a/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionConfigurationSource.java +++ b/src/main/java/org/springframework/data/gemfire/function/config/FunctionExecutionConfigurationSource.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2002-2018 the original author or authors. +======= + * Copyright 2002-2013 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -12,23 +16,25 @@ */ package org.springframework.data.gemfire.function.config; +import java.lang.annotation.Annotation; + import org.springframework.core.type.filter.TypeFilter; /** +<<<<<<< Updated upstream * Interface for function execution configuration sources (e.g., annotation or XML configuration) to configure * classpath scanning of annotated interfaces to implement proxies that invoke Gemfire functions * * @author David Turanski +======= + * Interface for Function Execution configuration sources (e.g. {@link Annotation} or XML configuration) + * to configure classpath scanning of annotated interfaces to implement proxies that invoke Functions. +>>>>>>> Stashed changes * + * @author David Turanski + * @author John Blum */ interface FunctionExecutionConfigurationSource { - /** - * Returns the actual source object that the configuration originated from. Will be used by the tooling to give visual - * feedback on where the repository instances actually come from. - * - * @return must not be {@literal null}. - */ - Object getSource(); /** * Returns the base packages the repository interfaces shall be found under. @@ -37,7 +43,6 @@ interface FunctionExecutionConfigurationSource { */ Iterable getBasePackages(); - /** * Returns configured {@link TypeFilter}s * @return include filters @@ -50,4 +55,12 @@ interface FunctionExecutionConfigurationSource { */ Iterable getExcludeFilters(); + /** + * Returns the actual source object that the configuration originated from. Will be used by the tooling to give visual + * feedback on where the repository instances actually come from. + * + * @return must not be {@literal null}. + */ + Object getSource(); + } diff --git a/src/main/java/org/springframework/data/gemfire/function/config/OnRegionExecutionBeanDefinitionBuilder.java b/src/main/java/org/springframework/data/gemfire/function/config/OnRegionExecutionBeanDefinitionBuilder.java index 70b334a6..b9a20491 100644 --- a/src/main/java/org/springframework/data/gemfire/function/config/OnRegionExecutionBeanDefinitionBuilder.java +++ b/src/main/java/org/springframework/data/gemfire/function/config/OnRegionExecutionBeanDefinitionBuilder.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2002-2018 the original author or authors. +======= + * Copyright 2002-2013 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -19,36 +23,36 @@ import org.springframework.data.gemfire.function.execution.OnRegionFunctionProxy /** * @author David Turanski - * + * @author John Blum */ class OnRegionExecutionBeanDefinitionBuilder extends AbstractFunctionExecutionBeanDefinitionBuilder { - /** - * @param configuration - */ OnRegionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) { super(configuration); } - - - /* (non-Javadoc) + /* + * (non-Javadoc) * @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder#getGemfireFunctionOperationsBeanDefinitionBuilder(org.springframework.beans.factory.support.BeanDefinitionRegistry) */ @Override protected BeanDefinitionBuilder getGemfireFunctionOperationsBeanDefinitionBuilder(BeanDefinitionRegistry registry) { - BeanDefinitionBuilder functionTemplateBuilder = BeanDefinitionBuilder.genericBeanDefinition(GemfireOnRegionFunctionTemplate.class); - functionTemplateBuilder.addConstructorArgReference((String)configuration.getAttribute("region")); + + BeanDefinitionBuilder functionTemplateBuilder = + BeanDefinitionBuilder.genericBeanDefinition(GemfireOnRegionFunctionTemplate.class); + + functionTemplateBuilder.addConstructorArgReference((String) this.configuration.getAttribute("region")); + return functionTemplateBuilder; } - /* (non-Javadoc) + /* + * (non-Javadoc) * @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder#getFunctionProxyFactoryBeanClass() */ @Override protected Class getFunctionProxyFactoryBeanClass() { return OnRegionFunctionProxyFactoryBean.class; } - } diff --git a/src/main/java/org/springframework/data/gemfire/function/config/TypeFilterParser.java b/src/main/java/org/springframework/data/gemfire/function/config/TypeFilterParser.java index 28e76262..85237f05 100644 --- a/src/main/java/org/springframework/data/gemfire/function/config/TypeFilterParser.java +++ b/src/main/java/org/springframework/data/gemfire/function/config/TypeFilterParser.java @@ -15,9 +15,12 @@ */ package org.springframework.data.gemfire.function.config; +import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; + import java.lang.annotation.Annotation; import java.util.Collection; import java.util.HashSet; +import java.util.Optional; import java.util.regex.Pattern; import org.springframework.beans.BeanUtils; @@ -25,6 +28,7 @@ import org.springframework.beans.FatalBeanException; import org.springframework.beans.factory.parsing.ReaderContext; import org.springframework.beans.factory.xml.XmlReaderContext; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.core.io.ResourceLoader; import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.core.type.filter.AspectJTypeFilter; import org.springframework.core.type.filter.AssignableTypeFilter; @@ -36,26 +40,37 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** +<<<<<<< Updated upstream * Parser to populate the given {@link ClassPathScanningCandidateComponentProvider} with {@link TypeFilter}s parsed from * the given {@link Element}'s children. +======= + * Parser to populate the given {@link ClassPathScanningCandidateComponentProvider} with {@link TypeFilter}s + * parsed from the given {@link Element}'s children. +>>>>>>> Stashed changes * * @author Oliver Gierke */ class TypeFilterParser { - private static final String FILTER_TYPE_ATTRIBUTE = "type"; private static final String FILTER_EXPRESSION_ATTRIBUTE = "expression"; + private static final String FILTER_TYPE_ATTRIBUTE = "type"; + + private final ClassLoader classLoader; private final ReaderContext readerContext; - private final ClassLoader classLoader; /** * Creates a new {@link TypeFilterParser} with the given {@link ReaderContext}. * * @param readerContext must not be {@literal null}. + * @see org.springframework.beans.factory.xml.XmlReaderContext */ public TypeFilterParser(XmlReaderContext readerContext) { - this(readerContext, readerContext.getResourceLoader().getClassLoader()); + + this(readerContext, Optional.ofNullable(readerContext) + .map(XmlReaderContext::getResourceLoader) + .map(ResourceLoader::getClassLoader) + .orElseGet(() -> Thread.currentThread().getContextClassLoader())); } /** @@ -76,20 +91,21 @@ class TypeFilterParser { public Iterable parseTypeFilters(Element element, Type type) { + Collection filters = new HashSet<>(); + NodeList nodeList = element.getChildNodes(); - Collection filters = new HashSet(); for (int i = 0; i < nodeList.getLength(); i++) { - Node node = nodeList.item(i); - Element childElement = type.getElement(node); + Element childElement = type.getElement(nodeList.item(i)); if (childElement != null) { - try { - filters.add(createTypeFilter(childElement, classLoader)); - } catch (RuntimeException e) { - readerContext.error(e.getMessage(), readerContext.extractSource(element), e.getCause()); + filters.add(createTypeFilter(childElement, this.classLoader)); + } + catch (RuntimeException cause) { + this.readerContext.error(cause.getMessage(), this.readerContext.extractSource(element), + cause.getCause()); } } } @@ -99,16 +115,17 @@ class TypeFilterParser { protected TypeFilter createTypeFilter(Element element, ClassLoader classLoader) { - String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE); String expression = element.getAttribute(FILTER_EXPRESSION_ATTRIBUTE); + String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE); try { FilterType filter = FilterType.fromString(filterType); + return filter.getFilter(expression, classLoader); - } catch (ClassNotFoundException ex) { - throw new FatalBeanException("Type filter class not found: " + expression, ex); + } catch (ClassNotFoundException cause) { + throw new FatalBeanException("TypeFilter class not found: " + expression, cause); } } @@ -119,109 +136,105 @@ class TypeFilterParser { * @author Oliver Gierke * @see #getFilter(String, ClassLoader) */ - private static enum FilterType { + private enum FilterType { ANNOTATION { + @Override @SuppressWarnings("unchecked") public TypeFilter getFilter(String expression, ClassLoader classLoader) throws ClassNotFoundException { - return new AnnotationTypeFilter((Class) classLoader.loadClass(expression)); } }, ASSIGNABLE { + @Override public TypeFilter getFilter(String expression, ClassLoader classLoader) throws ClassNotFoundException { - return new AssignableTypeFilter(classLoader.loadClass(expression)); } }, ASPECTJ { + @Override public TypeFilter getFilter(String expression, ClassLoader classLoader) { - return new AspectJTypeFilter(expression, classLoader); } - }, REGEX { + @Override public TypeFilter getFilter(String expression, ClassLoader classLoader) { - return new RegexPatternTypeFilter(Pattern.compile(expression)); } }, CUSTOM { + @Override public TypeFilter getFilter(String expression, ClassLoader classLoader) throws ClassNotFoundException { Class filterClass = classLoader.loadClass(expression); + if (!TypeFilter.class.isAssignableFrom(filterClass)) { - throw new IllegalArgumentException("Class is not assignable to [" + TypeFilter.class.getName() + "]: " - + expression); + throw newIllegalArgumentException("Class is not assignable to [%s]: %s", + TypeFilter.class.getName(), expression); } + return (TypeFilter) BeanUtils.instantiateClass(filterClass); } }; /** * Returns the {@link TypeFilter} for the given expression and {@link ClassLoader}. - * - * @param expression - * @param classLoader - * @return - * @throws ClassNotFoundException */ abstract TypeFilter getFilter(String expression, ClassLoader classLoader) throws ClassNotFoundException; /** * Returns the {@link FilterType} for the given type as {@link String}. * - * @param typeString - * @return + * @param type {@link String} containing the name of the type. + * @return {@link FilterType} for the given {@link String type name}. * @throws IllegalArgumentException if no {@link FilterType} could be found for the given argument. */ - static FilterType fromString(String typeString) { + static FilterType fromString(String type) { for (FilterType filter : FilterType.values()) { - if (filter.name().equalsIgnoreCase(typeString)) { + if (filter.name().equalsIgnoreCase(type)) { return filter; } } - throw new IllegalArgumentException("Unsupported filter type: " + typeString); + throw new IllegalArgumentException("Unsupported filter type: " + type); } } - static enum Type { + enum Type { - INCLUDE("include-filter"), EXCLUDE("exclude-filter"); + INCLUDE("include-filter"), + EXCLUDE("exclude-filter"); - private String elementName; - - private Type(String elementName) { + private final String elementName; + Type(String elementName) { this.elementName = elementName; } /** - * Returns the {@link Element} if the given {@link Node} is an {@link Element} and it's name equals the one of the - * type. - * - * @param node - * @return + * Returns the {@link Element} if the given {@link Node} is an {@link Element} and it's name equals + * the one of the type. */ Element getElement(Node node) { if (node.getNodeType() == Node.ELEMENT_NODE) { + String localName = node.getLocalName(); - if (elementName.equals(localName)) { + + if (this.elementName.equals(localName)) { return (Element) node; } } diff --git a/src/main/java/org/springframework/data/gemfire/function/config/XmlFunctionExecutionConfigurationSource.java b/src/main/java/org/springframework/data/gemfire/function/config/XmlFunctionExecutionConfigurationSource.java index e5101d00..857e6e05 100644 --- a/src/main/java/org/springframework/data/gemfire/function/config/XmlFunctionExecutionConfigurationSource.java +++ b/src/main/java/org/springframework/data/gemfire/function/config/XmlFunctionExecutionConfigurationSource.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2002-2018 the original author or authors. +======= + * Copyright 2002-2013 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -26,20 +30,26 @@ import org.w3c.dom.Element; * */ class XmlFunctionExecutionConfigurationSource extends AbstractFunctionExecutionConfigurationSource { - private static final String BASE_PACKAGE = "base-package"; - private Element element; - private ParserContext context; - private Iterable includeFilters; - private Iterable excludeFilters; - XmlFunctionExecutionConfigurationSource(Element element, ParserContext context) { - Assert.notNull(element); - Assert.notNull(context); + private static final String BASE_PACKAGE = "base-package"; + + private final Element element; + + private final Iterable includeFilters; + private final Iterable excludeFilters; + + private final ParserContext parserContext; + + XmlFunctionExecutionConfigurationSource(Element element, ParserContext parserContext) { + + Assert.notNull(element, "Element must not be null"); + Assert.notNull(parserContext, "ParserContext must not be null"); this.element = element; - this.context = context; + this.parserContext = parserContext; + + TypeFilterParser parser = new TypeFilterParser(parserContext.getReaderContext()); - TypeFilterParser parser = new TypeFilterParser(context.getReaderContext()); this.includeFilters = parser.parseTypeFilters(element, Type.INCLUDE); this.excludeFilters = parser.parseTypeFilters(element, Type.EXCLUDE); } @@ -49,7 +59,7 @@ class XmlFunctionExecutionConfigurationSource extends AbstractFunctionExecutionC */ @Override public Object getSource() { - return context.extractSource(element); + return this.parserContext.extractSource(this.element); } /* (non-Javadoc) @@ -57,7 +67,9 @@ class XmlFunctionExecutionConfigurationSource extends AbstractFunctionExecutionC */ @Override public Iterable getBasePackages() { - String attribute = element.getAttribute(BASE_PACKAGE); + + String attribute = this.element.getAttribute(BASE_PACKAGE); + return Arrays.asList(StringUtils.delimitedListToStringArray(attribute, ",", " ")); } @@ -67,7 +79,7 @@ class XmlFunctionExecutionConfigurationSource extends AbstractFunctionExecutionC */ @Override public Iterable getIncludeFilters() { - return includeFilters; + return this.includeFilters; } /* (non-Javadoc) @@ -75,7 +87,6 @@ class XmlFunctionExecutionConfigurationSource extends AbstractFunctionExecutionC */ @Override public Iterable getExcludeFilters() { - return excludeFilters; + return this.excludeFilters; } - } diff --git a/src/main/java/org/springframework/data/gemfire/function/execution/AbstractFunctionExecution.java b/src/main/java/org/springframework/data/gemfire/function/execution/AbstractFunctionExecution.java index 0ed222aa..e50a4d02 100644 --- a/src/main/java/org/springframework/data/gemfire/function/execution/AbstractFunctionExecution.java +++ b/src/main/java/org/springframework/data/gemfire/function/execution/AbstractFunctionExecution.java @@ -12,7 +12,7 @@ */ package org.springframework.data.gemfire.function.execution; -import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -25,7 +25,6 @@ import org.apache.geode.cache.execute.FunctionException; import org.apache.geode.cache.execute.FunctionService; import org.apache.geode.cache.execute.ResultCollector; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; /** * Base class for * Creating a GemFire {@link Execution} using {@link FunctionService}. Protected setters support @@ -51,14 +50,18 @@ abstract class AbstractFunctionExecution { private String functionId; public AbstractFunctionExecution(Function function, Object... args) { - Assert.notNull(function, "function cannot be null"); + + Assert.notNull(function, "Function cannot be null"); + this.function = function; this.functionId = function.getId(); this.args = args; } public AbstractFunctionExecution(String functionId, Object... args) { - Assert.isTrue(StringUtils.hasLength(functionId), "functionId cannot be null or empty"); + + Assert.hasText(functionId, "FunctionId cannot be null or empty"); + this.functionId = functionId; this.args = args; } @@ -67,23 +70,23 @@ abstract class AbstractFunctionExecution { } Object[] getArgs() { - return args; + return this.args; } ResultCollector getCollector() { - return resultCollector; + return this.resultCollector; } Function getFunction() { - return function; + return this.function; } String getFunctionId() { - return functionId; + return this.functionId; } long getTimeout() { - return timeout; + return this.timeout; } Iterable execute() { @@ -92,21 +95,22 @@ abstract class AbstractFunctionExecution { @SuppressWarnings("unchecked") Iterable execute(Boolean returnResult) { + Execution execution = getExecution(); - execution = execution.withArgs(getArgs()); - execution = (getCollector() == null ? execution : execution.withCollector(getCollector())); - execution = (getKeys() == null ? execution : execution.withFilter(getKeys())); + execution = execution.setArguments(getArgs()); + execution = getCollector() != null ? execution.withCollector(getCollector()) : execution; + execution = getKeys() != null ? execution.withFilter(getKeys()) : execution; ResultCollector resultCollector; if (isRegisteredFunction()) { - resultCollector = execution.execute(functionId); + resultCollector = execution.execute(this.functionId); } else { - resultCollector = execution.execute(function); + resultCollector = execution.execute(this.function); - if (!function.hasResult()) { + if (!this.function.hasResult()) { return null; } } @@ -116,7 +120,7 @@ abstract class AbstractFunctionExecution { } if (logger.isDebugEnabled()) { - logger.debug("using ResultsCollector " + resultCollector.getClass().getName()); + logger.debug("Using ResultsCollector " + resultCollector.getClass().getName()); } Iterable results = null; @@ -126,11 +130,8 @@ abstract class AbstractFunctionExecution { try { results = (Iterable) resultCollector.getResult(this.timeout, TimeUnit.MILLISECONDS); } - catch (FunctionException e) { - throw new RuntimeException(e); - } - catch (InterruptedException e) { - throw new RuntimeException(e); + catch (FunctionException | InterruptedException cause) { + throw new RuntimeException(cause); } } else { @@ -139,10 +140,10 @@ abstract class AbstractFunctionExecution { return replaceSingletonNullCollectionWithEmptyList(results); } - catch (FunctionException e) { - //TODO Come up with a better way to determine that the function should not return a result; - if (!e.getMessage().equals(NO_RESULT_MESSAGE)) { - throw e; + catch (FunctionException cause) { + // TODO Come up with a better way to determine that the function should not return a result; + if (!cause.getMessage().equals(NO_RESULT_MESSAGE)) { + throw cause; } } @@ -151,6 +152,7 @@ abstract class AbstractFunctionExecution { @SuppressWarnings("unchecked") T executeAndExtract() { + Iterable results = execute(); if (results == null || !results.iterator().hasNext()) { @@ -160,9 +162,9 @@ abstract class AbstractFunctionExecution { Object result = results.iterator().next(); if (result instanceof Throwable) { - throw new FunctionException(String.format("Execution of Function %1$s failed", - (function != null ? function.getClass().getName() : String.format("with ID '%1$s'", functionId))), - (Throwable) result); + throw new FunctionException(String.format("Execution of Function %s failed", + (this.function != null ? this.function.getClass().getName() + : String.format("with ID [%s]", this.functionId))), (Throwable) result); } return (T) result; @@ -200,11 +202,13 @@ abstract class AbstractFunctionExecution { } private boolean isRegisteredFunction() { - return function == null; + return this.function == null; } private Iterable replaceSingletonNullCollectionWithEmptyList(Iterable results) { + if (results != null) { + Iterator it = results.iterator(); if (!it.hasNext()) { @@ -212,11 +216,10 @@ abstract class AbstractFunctionExecution { } if (it.next() == null && !it.hasNext()) { - return new ArrayList(); + return Collections.emptyList(); } } return results; } - } diff --git a/src/main/java/org/springframework/data/gemfire/function/execution/GemfireFunctionProxyFactoryBean.java b/src/main/java/org/springframework/data/gemfire/function/execution/GemfireFunctionProxyFactoryBean.java index d0d381ac..81f8af26 100644 --- a/src/main/java/org/springframework/data/gemfire/function/execution/GemfireFunctionProxyFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/function/execution/GemfireFunctionProxyFactoryBean.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2002-2018 the original author or authors. +======= + * Copyright 2002-2013 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -35,7 +39,7 @@ import org.springframework.util.ClassUtils; * @see org.springframework.beans.factory.BeanClassLoaderAware * @see org.springframework.beans.factory.FactoryBean */ -public class GemfireFunctionProxyFactoryBean implements FactoryBean, MethodInterceptor, BeanClassLoaderAware { +public class GemfireFunctionProxyFactoryBean implements BeanClassLoaderAware, FactoryBean, MethodInterceptor { private volatile ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); @@ -56,6 +60,7 @@ public class GemfireFunctionProxyFactoryBean implements FactoryBean, Met * @param gemfireFunctionOperations an interface used to delegate the function invocation (typically a GemFire function template) */ public GemfireFunctionProxyFactoryBean(Class functionExecutionInterface, GemfireFunctionOperations gemfireFunctionOperations) { + Assert.notNull(functionExecutionInterface, "'functionExecutionInterface' must not be null"); Assert.isTrue(functionExecutionInterface.isInterface(), "'functionExecutionInterface' must be an interface"); @@ -65,16 +70,17 @@ public class GemfireFunctionProxyFactoryBean implements FactoryBean, Met } protected GemfireFunctionOperations getGemfireFunctionOperations() { - return gemfireFunctionOperations; + return this.gemfireFunctionOperations; } @Override public void setBeanClassLoader(ClassLoader classLoader) { - beanClassLoader = classLoader; + this.beanClassLoader = classLoader; } @Override public Object invoke(MethodInvocation invocation) throws Throwable { + if (AopUtils.isToStringMethod(invocation.getMethod())) { return "GemFire Function Proxy for service interface [" + this.functionExecutionInterface + "]"; } @@ -88,17 +94,18 @@ public class GemfireFunctionProxyFactoryBean implements FactoryBean, Met protected Object invokeFunction(Method method, Object[] args) { return this.gemfireFunctionOperations.executeAndExtract( - methodMetadata.getMethodMetadata(method).getFunctionId(), args); + this.methodMetadata.getMethodMetadata(method).getFunctionId(), args); } @Override public Object getObject() throws Exception { - if (functionExecutionProxy == null) { + + if (this.functionExecutionProxy == null) { onInit(); - Assert.notNull(functionExecutionProxy, "failed to initialize proxy"); + Assert.notNull(this.functionExecutionProxy, "failed to initialize proxy"); } - return functionExecutionProxy; + return this.functionExecutionProxy; } @Override @@ -112,11 +119,13 @@ public class GemfireFunctionProxyFactoryBean implements FactoryBean, Met } protected void onInit() { - if (!initialized) { - ProxyFactory proxyFactory = new ProxyFactory(functionExecutionInterface, this); - functionExecutionProxy = proxyFactory.getProxy(beanClassLoader); - initialized = true; + + if (!this.initialized) { + + ProxyFactory proxyFactory = new ProxyFactory(this.functionExecutionInterface, this); + + this.functionExecutionProxy = proxyFactory.getProxy(this.beanClassLoader); + this.initialized = true; } } - } diff --git a/src/main/java/org/springframework/data/gemfire/function/execution/GemfireOnRegionFunctionTemplate.java b/src/main/java/org/springframework/data/gemfire/function/execution/GemfireOnRegionFunctionTemplate.java index 1e4f285b..933efa20 100644 --- a/src/main/java/org/springframework/data/gemfire/function/execution/GemfireOnRegionFunctionTemplate.java +++ b/src/main/java/org/springframework/data/gemfire/function/execution/GemfireOnRegionFunctionTemplate.java @@ -20,11 +20,11 @@ import org.springframework.util.Assert; /** * @author David Turanski - * + * @author John Blum */ public class GemfireOnRegionFunctionTemplate extends AbstractFunctionTemplate implements GemfireOnRegionOperations { - private Region region; + private final Region region; /** * Constructs an instance of the GemFireOnRegionFunctionTemplate with the given GemFire Cache Region. @@ -33,37 +33,52 @@ public class GemfireOnRegionFunctionTemplate extends AbstractFunctionTemplate im * @see org.apache.geode.cache.Region */ public GemfireOnRegionFunctionTemplate(Region region) { - Assert.notNull(region, "Region cannot be null"); + + Assert.notNull(region, "Region must not be null"); + this.region = region; } @Override - public Iterable execute(Function function, Set keys, Object... args) { - return execute(new RegionFunctionExecution(region).setKeys(keys).setFunction(function).setTimeout(timeout) - .setArgs(args)); - } - - @Override - public Iterable execute(String functionId, Set keys, Object... args) { - return execute(new RegionFunctionExecution(region).setKeys(keys).setFunctionId(functionId).setTimeout(timeout) - .setArgs(args)); - } - - @Override - public T executeAndextract(String functionId, Set keys, Object... args) { - return this. executeAndExtract(new RegionFunctionExecution(region).setKeys(keys).setFunctionId(functionId) - .setTimeout(timeout).setArgs(args)); - } - - @Override - protected AbstractFunctionExecution getFunctionExecution() { + protected RegionFunctionExecution getFunctionExecution() { return new RegionFunctionExecution(this.region); } @Override - public void executeWithNoResult(String functionId, Set keys, Object... args) { - execute(new RegionFunctionExecution(region).setKeys(keys).setFunctionId(functionId).setTimeout(timeout) - .setArgs(args), false); + public Iterable execute(Function function, Set keys, Object... args) { + + return execute(getFunctionExecution() + .setKeys(keys) + .setFunction(function) + .setTimeout(this.timeout) + .setArgs(args)); } + @Override + public Iterable execute(String functionId, Set keys, Object... args) { + + return execute(getFunctionExecution() + .setKeys(keys).setFunctionId(functionId) + .setTimeout(this.timeout) + .setArgs(args)); + } + + @Override + public T executeAndextract(String functionId, Set keys, Object... args) { + + return executeAndExtract(getFunctionExecution() + .setKeys(keys) + .setFunctionId(functionId) + .setTimeout(this.timeout).setArgs(args)); + } + + @Override + public void executeWithNoResult(String functionId, Set keys, Object... args) { + + execute(getFunctionExecution() + .setKeys(keys) + .setFunctionId(functionId) + .setTimeout(this.timeout) + .setArgs(args), false); + } } diff --git a/src/main/java/org/springframework/data/gemfire/function/execution/OnRegionFunctionProxyFactoryBean.java b/src/main/java/org/springframework/data/gemfire/function/execution/OnRegionFunctionProxyFactoryBean.java index a33989be..68f1610c 100644 --- a/src/main/java/org/springframework/data/gemfire/function/execution/OnRegionFunctionProxyFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/function/execution/OnRegionFunctionProxyFactoryBean.java @@ -1,5 +1,9 @@ /* +<<<<<<< Updated upstream * Copyright 2002-2018 the original author or authors. +======= + * Copyright 2002-2013 the original author or authors. +>>>>>>> Stashed changes * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -23,38 +27,41 @@ import org.springframework.data.gemfire.util.ArrayUtils; */ public class OnRegionFunctionProxyFactoryBean extends GemfireFunctionProxyFactoryBean { - private OnRegionExecutionMethodMetadata methodMetadata; + private final OnRegionExecutionMethodMetadata methodMetadata; /** * @param serviceInterface the Service class interface specifying the operations to proxy. * @param gemfireOnRegionOperations an {@link GemfireOnRegionOperations} instance */ - public OnRegionFunctionProxyFactoryBean(Class serviceInterface, GemfireOnRegionOperations gemfireOnRegionOperations) { + public OnRegionFunctionProxyFactoryBean(Class serviceInterface, + GemfireOnRegionOperations gemfireOnRegionOperations) { + super(serviceInterface, gemfireOnRegionOperations); - methodMetadata = new OnRegionExecutionMethodMetadata(serviceInterface); + + this.methodMetadata = new OnRegionExecutionMethodMetadata(serviceInterface); } @Override protected Iterable invokeFunction(Method method, Object[] args) { - GemfireOnRegionOperations gemfireOnRegionOperations = (GemfireOnRegionOperations) getGemfireFunctionOperations(); - OnRegionMethodMetadata onRegionMethodMetadata = methodMetadata.getMethodMetadata(method); + GemfireOnRegionOperations gemfireOnRegionOperations = + (GemfireOnRegionOperations) getGemfireFunctionOperations(); + + OnRegionMethodMetadata onRegionMethodMetadata = this.methodMetadata.getMethodMetadata(method); int filterArgPosition = onRegionMethodMetadata.getFilterArgPosition(); + String functionId = onRegionMethodMetadata.getFunctionId(); Set filter = null; - /* - * extract filter from args if necessary - */ + // extract filter from args if necessary if (filterArgPosition >= 0) { filter = (Set) args[filterArgPosition]; args = ArrayUtils.remove(args, filterArgPosition); } - return (filter == null ? gemfireOnRegionOperations.execute(functionId, args) - : gemfireOnRegionOperations.execute(functionId, filter, args)); + return filter != null ? gemfireOnRegionOperations.execute(functionId, filter, args) + : gemfireOnRegionOperations.execute(functionId, args); } - } diff --git a/src/main/java/org/springframework/data/gemfire/function/execution/RegionFunctionExecution.java b/src/main/java/org/springframework/data/gemfire/function/execution/RegionFunctionExecution.java index 0693e5ff..52c7f9b9 100644 --- a/src/main/java/org/springframework/data/gemfire/function/execution/RegionFunctionExecution.java +++ b/src/main/java/org/springframework/data/gemfire/function/execution/RegionFunctionExecution.java @@ -26,12 +26,11 @@ import org.springframework.util.CollectionUtils; */ class RegionFunctionExecution extends AbstractFunctionExecution { - private final Region region; + private volatile Set keys; public RegionFunctionExecution(Region region) { - super(); this.region = region; } @@ -48,11 +47,17 @@ class RegionFunctionExecution extends AbstractFunctionExecution { * @see org.springframework.data.gemfire.function.FunctionExecution#getExecution() */ @Override + @SuppressWarnings("unchecked") protected Execution getExecution() { - Execution execution = FunctionService.onRegion(region); - if (!CollectionUtils.isEmpty(this.keys) ) { + + Execution execution = FunctionService.onRegion(this.region); + + Set keys = getKeys(); + + if (!CollectionUtils.isEmpty(keys) ) { execution = execution.withFilter(keys); } + return execution; } } diff --git a/src/main/java/org/springframework/data/gemfire/util/CacheUtils.java b/src/main/java/org/springframework/data/gemfire/util/CacheUtils.java index 7731348d..72bef5a6 100644 --- a/src/main/java/org/springframework/data/gemfire/util/CacheUtils.java +++ b/src/main/java/org/springframework/data/gemfire/util/CacheUtils.java @@ -25,6 +25,7 @@ import org.apache.geode.cache.CacheFactory; import org.apache.geode.cache.GemFireCache; import org.apache.geode.cache.client.ClientCache; import org.apache.geode.cache.client.ClientCacheFactory; +import org.apache.geode.cache.client.Pool; import org.apache.geode.distributed.DistributedSystem; import org.apache.geode.internal.cache.GemFireCacheImpl; import org.springframework.util.StringUtils; @@ -50,7 +51,6 @@ public abstract class CacheUtils extends DistributedSystemUtils { public static final String DEFAULT_POOL_NAME = "DEFAULT"; - /* (non-Javadoc) */ @SuppressWarnings("all") public static boolean isClient(GemFireCache cache) { @@ -63,10 +63,25 @@ public abstract class CacheUtils extends DistributedSystemUtils { return client; } - /* (non-Javadoc) */ + public static boolean isDefaultPool(Pool pool) { + return Optional.ofNullable(pool).map(Pool::getName).filter(CacheUtils::isDefaultPool).isPresent(); + } + + public static boolean isNotDefaultPool(Pool pool) { + return !isDefaultPool(pool); + } + + public static boolean isDefaultPool(String poolName) { + return DEFAULT_POOL_NAME.equals(poolName); + } + + public static boolean isNotDefaultPool(String poolName) { + return !isDefaultPool(poolName); + } + public static boolean isDurable(ClientCache clientCache) { - // NOTE technically the following code snippet would be more useful/valuable but is not "testable"! + // NOTE: Technically, the following code snippet would be more useful/valuable but is not "testable"! //((InternalDistributedSystem) distributedSystem).getConfig().getDurableClientId(); return Optional.ofNullable(clientCache) @@ -78,7 +93,6 @@ public abstract class CacheUtils extends DistributedSystemUtils { .isPresent(); } - /* (non-Javadoc) */ @SuppressWarnings("all") public static boolean isPeer(GemFireCache cache) { @@ -91,17 +105,14 @@ public abstract class CacheUtils extends DistributedSystemUtils { return peer; } - /* (non-Javadoc) */ public static boolean close() { return close(resolveGemFireCache()); } - /* (non-Javadoc) */ public static boolean close(GemFireCache gemfireCache) { return close(gemfireCache, () -> {}); } - /* (non-Javadoc) */ public static boolean close(GemFireCache gemfireCache, Runnable shutdownHook) { try { @@ -116,7 +127,6 @@ public abstract class CacheUtils extends DistributedSystemUtils { } } - /* (non-Javadoc) */ public static boolean closeCache() { try { @@ -128,7 +138,6 @@ public abstract class CacheUtils extends DistributedSystemUtils { } } - /* (non-Javadoc) */ public static boolean closeClientCache() { try { @@ -140,7 +149,6 @@ public abstract class CacheUtils extends DistributedSystemUtils { } } - /* (non-Javadoc) */ public static Cache getCache() { try { @@ -151,7 +159,6 @@ public abstract class CacheUtils extends DistributedSystemUtils { } } - /* (non-Javadoc) */ public static ClientCache getClientCache() { try { @@ -162,7 +169,6 @@ public abstract class CacheUtils extends DistributedSystemUtils { } } - /* (non-Javadoc) */ public static GemFireCache resolveGemFireCache() { return Optional.ofNullable(getClientCache()).orElseGet(CacheUtils::getCache); } diff --git a/src/main/java/org/springframework/data/gemfire/util/RegionUtils.java b/src/main/java/org/springframework/data/gemfire/util/RegionUtils.java index 11fdd218..38f5aed2 100644 --- a/src/main/java/org/springframework/data/gemfire/util/RegionUtils.java +++ b/src/main/java/org/springframework/data/gemfire/util/RegionUtils.java @@ -18,10 +18,14 @@ package org.springframework.data.gemfire.util; import java.util.Optional; +import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionAttributes; +import org.apache.geode.cache.client.ClientRegionShortcut; +import org.springframework.data.gemfire.client.ClientRegionShortcutWrapper; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -35,6 +39,53 @@ import org.springframework.util.StringUtils; @SuppressWarnings("unused") public abstract class RegionUtils extends CacheUtils { + /** + * Assert that the configuration settings for {@link ClientRegionShortcut} and the {@literal persistent} attribute + * in <gfe:*-region> elements are compatible. + * + * @param resolvedShortcut {@link ClientRegionShortcut} resolved from the SDG XML namespace. + * @param persistent boolean indicating the value of the {@literal persistent} configuration attribute. + * @see org.springframework.data.gemfire.client.ClientRegionShortcutWrapper + * @see org.apache.geode.cache.client.ClientRegionShortcut + */ + public static void assertClientRegionShortcutAndPersistentAttributeAreCompatible( + ClientRegionShortcut resolvedShortcut, Boolean persistent) { + + boolean persistentUnspecified = persistent == null; + + if (ClientRegionShortcutWrapper.valueOf(resolvedShortcut).isPersistent()) { + Assert.isTrue(persistentUnspecified || Boolean.TRUE.equals(persistent), + String.format("Client Region Shortcut [%s] is not valid when persistent is false", resolvedShortcut)); + } + else { + Assert.isTrue(persistentUnspecified || Boolean.FALSE.equals(persistent), + String.format("Client Region Shortcut [%s] is not valid when persistent is true", resolvedShortcut)); + } + } + + /** + * Assert that the configuration settings for {@link DataPolicy} and the {@literal persistent} attribute + * in <gfe:*-region> elements are compatible. + * + * @param resolvedDataPolicy {@link DataPolicy} resolved from the SDG XML namespace. + * @param persistent boolean indicating the value of the {@literal persistent} configuration attribute. + * @see org.apache.geode.cache.DataPolicy + */ + public static void assertDataPolicyAndPersistentAttributeAreCompatible( + DataPolicy resolvedDataPolicy, Boolean persistent) { + + boolean persistentUnspecified = persistent == null; + + if (resolvedDataPolicy.withPersistence()) { + Assert.isTrue(persistentUnspecified || Boolean.TRUE.equals(persistent), + String.format("Data Policy [%s] is not valid when persistent is false", resolvedDataPolicy)); + } + else { + Assert.isTrue(persistentUnspecified || Boolean.FALSE.equals(persistent), + String.format("Data Policy [%s] is not valid when persistent is true", resolvedDataPolicy)); + } + } + public static boolean isClient(Region region) { return Optional.ofNullable(region) @@ -44,13 +95,11 @@ public abstract class RegionUtils extends CacheUtils { .isPresent(); } - /* (non-Javadoc) */ @Nullable public static String toRegionName(@Nullable Region region) { return Optional.ofNullable(region).map(Region::getName).orElse(null); } - /* (non-Javadoc) */ @Nullable public static String toRegionName(String regionPath) { @@ -63,13 +112,11 @@ public abstract class RegionUtils extends CacheUtils { .orElse(regionPath); } - /* (non-Javadoc) */ @Nullable public static String toRegionPath(@Nullable Region region) { return Optional.ofNullable(region).map(Region::getFullPath).orElse(null); } - /* (non-Javadoc) */ @NonNull public static String toRegionPath(String regionName) { return String.format("%1$s%2$s", Region.SEPARATOR, regionName); diff --git a/src/main/java/org/springframework/data/gemfire/util/SpringUtils.java b/src/main/java/org/springframework/data/gemfire/util/SpringUtils.java index 7b5dd73e..6c60bccf 100644 --- a/src/main/java/org/springframework/data/gemfire/util/SpringUtils.java +++ b/src/main/java/org/springframework/data/gemfire/util/SpringUtils.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.function.Function; import java.util.function.Supplier; @@ -39,10 +38,8 @@ import org.springframework.util.StringUtils; * @since 1.8.0 */ @SuppressWarnings("unused") -// TODO rename this utility class using a more descriptive, intuitive and meaningful name public abstract class SpringUtils { - /* (non-Javadoc) */ public static BeanDefinition addDependsOn(BeanDefinition bean, String... beanNames) { List dependsOnList = new ArrayList<>(); @@ -54,7 +51,6 @@ public abstract class SpringUtils { return bean; } - /* (non-Javadoc) */ public static BeanDefinition setPropertyReference(BeanDefinition beanDefinition, String propertyName, String beanName) { @@ -63,7 +59,6 @@ public abstract class SpringUtils { return beanDefinition; } - /* (non-Javadoc) */ public static BeanDefinition setPropertyValue(BeanDefinition beanDefinition, String propertyName, Object propertyValue) { @@ -72,58 +67,60 @@ public abstract class SpringUtils { return beanDefinition; } - /* (non-Javadoc) */ public static String defaultIfEmpty(String value, String defaultValue) { - return (StringUtils.hasText(value) ? value : defaultValue); + return defaultIfEmpty(value, () -> defaultValue); + } + + public static String defaultIfEmpty(String value, Supplier supplier) { + return StringUtils.hasText(value) ? value : supplier.get(); } - /* (non-Javadoc) */ public static T defaultIfNull(T value, T defaultValue) { - return Optional.ofNullable(value).orElse(defaultValue); + return defaultIfNull(value, () -> defaultValue); } - /* (non-Javadoc) */ public static T defaultIfNull(T value, Supplier supplier) { - return Optional.ofNullable(value).orElseGet(supplier); + return value != null ? value : supplier.get(); } - /* (non-Javadoc) */ public static String dereferenceBean(String beanName) { return String.format("%1$s%2$s", BeanFactory.FACTORY_BEAN_PREFIX, beanName); } - /* (non-Javadoc) */ public static boolean equalsIgnoreNull(Object obj1, Object obj2) { - return (obj1 == null ? obj2 == null : obj1.equals(obj2)); + return obj1 == null ? obj2 == null : obj1.equals(obj2); } - /* (non-Javadoc) */ public static boolean nullOrEquals(Object obj1, Object obj2) { - return (obj1 == null || obj1.equals(obj2)); + return obj1 == null || obj1.equals(obj2); } - /* (non-Javadoc) */ public static boolean nullSafeEquals(Object obj1, Object obj2) { - return (obj1 != null && obj1.equals(obj2)); + return obj1 != null && obj1.equals(obj2); + } + + public static String nullSafeName(Class type) { + return type != null ? type.getName() : null; + } + + public static String nullSafeSimpleName(Class type) { + return type != null ? type.getSimpleName() : null; } - /* (non-Javadoc) */ public static T safeGetValue(Supplier valueSupplier) { return safeGetValue(valueSupplier, (T) null); } - /* (non-Javadoc) */ public static T safeGetValue(Supplier valueSupplier, T defaultValue) { return safeGetValue(valueSupplier, (Supplier) () -> defaultValue); } - /* (non-Javadoc) */ public static T safeGetValue(Supplier valueSupplier, Supplier defaultValueSupplier) { return safeGetValue(valueSupplier, (Function) exception -> defaultValueSupplier.get()); } - /* (non-Javadoc) */ public static T safeGetValue(Supplier valueSupplier, Function exceptionHandler) { + try { return valueSupplier.get(); } diff --git a/src/test/java/org/springframework/data/gemfire/AutoRegionLookupIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/AutoRegionLookupIntegrationTests.java index 32dba3d1..fb6e7b3e 100644 --- a/src/test/java/org/springframework/data/gemfire/AutoRegionLookupIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/AutoRegionLookupIntegrationTests.java @@ -23,11 +23,10 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; /** - * The AutoRegionLookupIntegrationTests class is a test suite of test cases testing the contract and functionality - * of Spring Data GemFire's new auto Region lookup feature. + * Integration tests to test the contract and functionality of Spring Data GemFire's Auto Region Lookup functionality. * * @author John Blum * @see org.junit.Test @@ -36,7 +35,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner * @since 1.5.0 */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration @SuppressWarnings("unused") public class AutoRegionLookupIntegrationTests { @@ -54,5 +53,4 @@ public class AutoRegionLookupIntegrationTests { assertTrue(applicationContext.containsBean("/NativeReplicateParent/NativeReplicateChild")); assertTrue(applicationContext.containsBean("/NativeReplicateParent/NativeReplicateChild/NativeReplicateGrandchild")); } - } diff --git a/src/test/java/org/springframework/data/gemfire/AutoRegionLookupWithAutowiringIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/AutoRegionLookupWithAutowiringIntegrationTests.java index 37f8671b..50376bca 100644 --- a/src/test/java/org/springframework/data/gemfire/AutoRegionLookupWithAutowiringIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/AutoRegionLookupWithAutowiringIntegrationTests.java @@ -29,11 +29,11 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; /** - * The AutoRegionLookupWithAutowiringIntegrationTests class is a test suite class testing the behavior of - * Spring Data GemFire's auto Region lookup functionality when combined with Spring's component auto-wiring capabilities. + * Integration tests to test the behavior of Spring Data GemFire's Auto Region Lookup functionality + * when combined with Spring's component auto-wiring capabilities. * * @author John Blum * @see org.junit.Test @@ -42,7 +42,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner * @since 1.5.0 */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration @SuppressWarnings("unused") public class AutoRegionLookupWithAutowiringIntegrationTests { @@ -50,24 +50,24 @@ public class AutoRegionLookupWithAutowiringIntegrationTests { @Autowired private TestComponent testComponent; - protected static void assertRegionMetaData(final Region region, - final String expectedName, final DataPolicy expectedDataPolicy) { + private static void assertRegionMetaData(Region region, String expectedName, DataPolicy expectedDataPolicy) { assertRegionMetaData(region, expectedName, Region.SEPARATOR + expectedName, expectedDataPolicy); } - protected static void assertRegionMetaData(final Region region, final String expectedName, - final String expectedFullPath, final DataPolicy expectedDataPolicy) { + private static void assertRegionMetaData(Region region, String expectedName, String expectedFullPath, + DataPolicy expectedDataPolicy) { + assertNotNull(String.format("Region (%1$s) was not properly configured and initialized!", expectedName), region); assertEquals(expectedName, region.getName()); assertEquals(expectedFullPath, region.getFullPath()); - assertNotNull(String.format("Region (%1$s) must have RegionAttributes defined!", expectedName), - region.getAttributes()); + assertNotNull(String.format("Region (%1$s) must have RegionAttributes defined!", expectedName), region.getAttributes()); assertEquals(expectedDataPolicy, region.getAttributes().getDataPolicy()); assertFalse(region.getAttributes().getDataPolicy().withPersistence()); } @Test public void testAutowiredNativeRegions() { + assertRegionMetaData(testComponent.nativePartitionedRegion, "NativePartitionedRegion", DataPolicy.PARTITION); assertRegionMetaData(testComponent.nativeReplicateParent, "NativeReplicateParent", DataPolicy.REPLICATE); assertRegionMetaData(testComponent.nativeReplicateChild, "NativeReplicateChild", @@ -92,5 +92,4 @@ public class AutoRegionLookupWithAutowiringIntegrationTests { Region nativeReplicateGrandchild; } - } diff --git a/src/test/java/org/springframework/data/gemfire/AutoRegionLookupWithComponentScanningIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/AutoRegionLookupWithComponentScanningIntegrationTests.java index 8febe270..d99eb59f 100644 --- a/src/test/java/org/springframework/data/gemfire/AutoRegionLookupWithComponentScanningIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/AutoRegionLookupWithComponentScanningIntegrationTests.java @@ -24,11 +24,11 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; /** - * The AutoRegionLookupWithComponentScanningIntegrationTests class is a test suite class testing the behavior of - * Spring Data GemFire's auto Region lookup behavior with Spring component scanning functionality. + * Integration tests to test the behavior of Spring Data GemFire's Auto Region Lookup behavior + * with Spring component scanning functionality. * * @author John Blum * @see org.junit.Test @@ -37,19 +37,19 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner * @since 1.5.0 */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration @SuppressWarnings("unused") public class AutoRegionLookupWithComponentScanningIntegrationTests { @Autowired - private ApplicationContext context; + private ApplicationContext applicationContext; @Test public void testAutowiredNativeRegions() { - assertTrue("The 'autoRegionLookupDao' Spring bean DAO was not properly configured an initialized!", - context.containsBean("autoRegionLookupDao")); - assertNotNull(context.getBean("autoRegionLookupDao", AutoRegionLookupDao.class)); - } + assertTrue("The 'autoRegionLookupDao' Spring bean DAO was not properly configured an initialized!", + this.applicationContext.containsBean("autoRegionLookupDao")); + assertNotNull(this.applicationContext.getBean("autoRegionLookupDao", AutoRegionLookupDao.class)); + } } diff --git a/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java index 0d3fa3be..226fe116 100644 --- a/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java @@ -16,10 +16,12 @@ package org.springframework.data.gemfire; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newRuntimeException; import java.io.File; import java.io.IOException; @@ -45,8 +47,8 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.data.gemfire.fork.LocatorProcess; -import org.springframework.data.gemfire.process.ProcessExecutor; import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; import org.springframework.data.gemfire.test.support.FileUtils; import org.springframework.data.gemfire.test.support.ThreadUtils; import org.springframework.data.gemfire.test.support.ThrowableUtils; @@ -69,7 +71,7 @@ import org.springframework.util.StringUtils; * @since 1.5.0 */ @SuppressWarnings("unused") -public class CacheClusterConfigurationIntegrationTest { +public class CacheClusterConfigurationIntegrationTest extends ClientServerIntegrationTestsSupport { private static File locatorWorkingDirectory; @@ -77,11 +79,14 @@ public class CacheClusterConfigurationIntegrationTest { private static List locatorProcessOutput = Collections.synchronizedList(new ArrayList()); + private static final String LOG_LEVEL = "error"; + @Rule public TestRule watchman = new TestWatcher() { + @Override protected void failed(Throwable throwable, Description description) { - System.err.println(String.format("Test '%1$s' failed...", description.getDisplayName())); + System.err.printf("Test [%s] failed...%n", description.getDisplayName()); System.err.println(ThrowableUtils.toString(throwable)); System.err.println("Locator process log file contents were..."); System.err.println(getLocatorProcessOutput(description)); @@ -89,36 +94,42 @@ public class CacheClusterConfigurationIntegrationTest { @Override protected void finished(Description description) { + if (Boolean.valueOf(System.getProperty("spring.gemfire.fork.clean", Boolean.TRUE.toString()))) { try { FileUtils.write(new File(locatorWorkingDirectory.getParent(), - String.format("%1$s-clusterconfiglocator.log", description.getMethodName())), + String.format("%s-clusterconfiglocator.log", description.getMethodName())), getLocatorProcessOutput(description)); } - catch (IOException e) { - throw new RuntimeException("Failed the write the contents of the Locator process log to a file!", e); + catch (IOException cause) { + throw newRuntimeException(cause, "Failed the write the contents of the Locator process log to a file"); } } } private String getLocatorProcessOutput(Description description) { + try { String locatorProcessOutputString = StringUtils.collectionToDelimitedString(locatorProcessOutput, FileUtils.LINE_SEPARATOR, String.format("[%1$s] - ", description.getMethodName()), ""); - locatorProcessOutputString = (StringUtils.hasText(locatorProcessOutputString) ? - locatorProcessOutputString : locatorProcess.readLogFile()); + locatorProcessOutputString = StringUtils.hasText(locatorProcessOutputString) + ? locatorProcessOutputString : locatorProcess.readLogFile(); return locatorProcessOutputString; } - catch (IOException e) { - throw new RuntimeException("Failed to read the contents of the Locator process log file!", e); + catch (IOException cause) { + throw newRuntimeException(cause, "Failed to read the contents of the Locator process log file"); } } }; @BeforeClass - public static void testSuiteSetup() throws IOException { + @SuppressWarnings("all") + public static void startLocator() throws IOException { + + int availablePort = findAvailablePort(); + String locatorName = "ClusterConfigLocator"; locatorWorkingDirectory = new File(System.getProperty("user.dir"), locatorName.toLowerCase()); @@ -130,12 +141,12 @@ public class CacheClusterConfigurationIntegrationTest { List arguments = new ArrayList<>(); arguments.add("-Dgemfire.name=" + locatorName); - arguments.add("-Dgemfire.mcast-port=0"); - arguments.add("-Dgemfire.log-level=error"); arguments.add("-Dspring.data.gemfire.enable-cluster-configuration=true"); arguments.add("-Dspring.data.gemfire.load-cluster-configuration=true"); + arguments.add(String.format("-Dgemfire.log-level=%s", LOG_LEVEL)); + arguments.add(String.format("-Dspring.data.gemfire.locator.port=%d", availablePort)); - locatorProcess = ProcessExecutor.launch(locatorWorkingDirectory, LocatorProcess.class, + locatorProcess = run(locatorWorkingDirectory, LocatorProcess.class, arguments.toArray(new String[arguments.size()])); locatorProcess.register(input -> locatorProcessOutput.add(input)); @@ -144,66 +155,84 @@ public class CacheClusterConfigurationIntegrationTest { waitForLocatorStart(TimeUnit.SECONDS.toMillis(30)); - System.out.println("Cluster Configuration Locator should be running!"); + System.setProperty("spring.data.gemfire.locator.port", String.valueOf(availablePort)); } private static void waitForLocatorStart(final long milliseconds) { + ThreadUtils.timedWait(milliseconds, 500, new ThreadUtils.WaitCondition() { + File pidControlFile = new File(locatorWorkingDirectory, LocatorProcess.getLocatorProcessControlFilename()); - @Override public boolean waiting() { + + @Override + public boolean waiting() { return !pidControlFile.isFile(); } }); } @AfterClass - public static void testSuiteTearDown() { + public static void stopLocator() { + locatorProcess.shutdown(); + + System.clearProperty("spring.data.gemfire.locator.port"); + if (Boolean.valueOf(System.getProperty("spring.gemfire.fork.clean", Boolean.TRUE.toString()))) { FileSystemUtils.deleteRecursively(locatorWorkingDirectory); } } - protected Region assertRegion(final Region actualRegion, final String expectedRegionName) { + private Region assertRegion(Region actualRegion, String expectedRegionName) { return assertRegion(actualRegion, expectedRegionName, Region.SEPARATOR+expectedRegionName); } - protected Region assertRegion(final Region actualRegion, final String expectedRegionName, final String expectedRegionFullPath) { - assertNotNull(String.format("The '%1$s' was not properly configured and initialized!", expectedRegionName), actualRegion); + private Region assertRegion(Region actualRegion, String expectedRegionName, String expectedRegionFullPath) { + + assertNotNull(String.format("The [%s] was not properly configured and initialized!", + expectedRegionName), actualRegion); assertEquals(expectedRegionName, actualRegion.getName()); assertEquals(expectedRegionFullPath, actualRegion.getFullPath()); + return actualRegion; } - protected Region assertRegionAttributes(final Region actualRegion, final DataPolicy expectedDataPolicy, final Scope expectedScope) { + private Region assertRegionAttributes(Region actualRegion, DataPolicy expectedDataPolicy, Scope expectedScope) { + assertNotNull(actualRegion); assertNotNull(actualRegion.getAttributes()); assertEquals(expectedDataPolicy, actualRegion.getAttributes().getDataPolicy()); assertEquals(expectedScope, actualRegion.getAttributes().getScope()); + return actualRegion; } - protected String getLocation(final String configLocation) { + private String getLocation(String configLocation) { + String baseLocation = getClass().getPackage().getName().replace('.', File.separatorChar); + return baseLocation.concat(File.separator).concat(configLocation); } - protected Region getRegion(ConfigurableApplicationContext applicationContext, String regionBeanName) { + private Region getRegion(ConfigurableApplicationContext applicationContext, String regionBeanName) { return applicationContext.getBean(regionBeanName, Region.class); } - protected ConfigurableApplicationContext newApplicationContext(String... configLocations) { + private ConfigurableApplicationContext newApplicationContext(String... configLocations) { + ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext(configLocations); + applicationContext.registerShutdownHook(); + return applicationContext; } @Test @Ignore - // TODO re-enable the test once the GemFire Cluster Configuration Service race condition has been properly fixed! public void clusterConfigurationTest() { - ConfigurableApplicationContext applicationContext = newApplicationContext( - getLocation("cacheUsingClusterConfigurationIntegrationTest.xml")); + + ConfigurableApplicationContext applicationContext = + newApplicationContext(getLocation("cacheUsingClusterConfigurationIntegrationTest.xml")); assertRegionAttributes(assertRegion(getRegion(applicationContext, "ClusterConfigRegion"), "ClusterConfigRegion"), DataPolicy.PARTITION, Scope.DISTRIBUTED_NO_ACK); @@ -223,17 +252,20 @@ public class CacheClusterConfigurationIntegrationTest { @Test public void localConfigurationTest() { + try { - newApplicationContext(getLocation("cacheUsingLocalOnlyConfigurationIntegrationTest.xml")); + newApplicationContext(getLocation("cacheUsingLocalConfigurationIntegrationTest.xml")); fail("Loading the 'cacheUsingLocalOnlyConfigurationIntegrationTest.xml' Spring ApplicationContext" + " configuration file should have resulted in an Exception due to the Region lookup on" + " 'ClusterConfigRegion' when GemFire Cluster Configuration is disabled!"); } catch (BeanCreationException expected) { - assertTrue(expected.getCause() instanceof BeanInitializationException); - assertTrue(expected.getCause().getMessage().matches( - "Region \\[ClusterConfigRegion\\] in Cache \\[.*\\] not found")); + + assertThat(expected).hasCauseInstanceOf(BeanInitializationException.class); + + assertTrue(String.format("Message was [%s]", expected.getMessage()), expected.getCause().getMessage() + .matches("Region \\[ClusterConfigRegion\\] in Cache \\[.*\\] not found")); } } } diff --git a/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java index f611f94c..507e0873 100644 --- a/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java @@ -32,8 +32,10 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.same; +import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; @@ -56,10 +58,9 @@ import org.apache.geode.cache.util.GatewayConflictResolver; import org.apache.geode.distributed.DistributedMember; import org.apache.geode.distributed.DistributedSystem; import org.apache.geode.pdx.PdxSerializer; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; +import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.beans.factory.BeanFactory; @@ -94,34 +95,27 @@ public class CacheFactoryBeanTest { @Mock private Cache mockCache; - @Rule - public ExpectedException exception = ExpectedException.none(); - @Test - public void afterPropertiesSet() throws Exception { - final AtomicBoolean postProcessBeforeCacheInitializationCalled = new AtomicBoolean(false); - final Properties gemfireProperties = new Properties(); + public void afterPropertiesSetAppliesCacheConfigurersAndThenInitializesBeanFactoryLocator() throws Exception { - CacheFactoryBean cacheFactoryBean = new CacheFactoryBean() { + CacheFactoryBean cacheFactoryBean = spy(new CacheFactoryBean()); - @Override - protected void postProcessBeforeCacheInitialization(Properties actualGemfireProperties) { - assertThat(actualGemfireProperties, is(sameInstance(gemfireProperties))); - postProcessBeforeCacheInitializationCalled.set(true); - } - }; - - cacheFactoryBean.setProperties(gemfireProperties); cacheFactoryBean.afterPropertiesSet(); - assertThat(postProcessBeforeCacheInitializationCalled.get(), is(true)); + InOrder orderVerifier = inOrder(cacheFactoryBean); + + orderVerifier.verify(cacheFactoryBean, times(1)).applyCacheConfigurers(); + orderVerifier.verify(cacheFactoryBean, times(1)).initBeanFactoryLocator(); } @Test - public void postProcessBeforeCacheInitializationUsingDefaults() { - Properties gemfireProperties = new Properties(); + public void applyingCacheConfigurersDisablesAutoReconnectAndDoesNotUseClusterConfigurationByDefault() { - new CacheFactoryBean().postProcessBeforeCacheInitialization(gemfireProperties); + CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); + + cacheFactoryBean.applyCacheConfigurers(); + + Properties gemfireProperties = cacheFactoryBean.getProperties(); assertThat(gemfireProperties.size(), is(equalTo(2))); assertThat(gemfireProperties.containsKey("disable-auto-reconnect"), is(true)); @@ -131,13 +125,15 @@ public class CacheFactoryBeanTest { } @Test - public void postProcessBeforeCacheInitializationWithAutoReconnectAndClusterConfigurationDisabled() { - Properties gemfireProperties = new Properties(); + public void applyCacheConfigurersWithAutoReconnectAndClusterConfigurationDisabled() { + CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); cacheFactoryBean.setEnableAutoReconnect(false); cacheFactoryBean.setUseClusterConfiguration(false); - cacheFactoryBean.postProcessBeforeCacheInitialization(gemfireProperties); + cacheFactoryBean.applyCacheConfigurers(); + + Properties gemfireProperties = cacheFactoryBean.getProperties(); assertThat(gemfireProperties.size(), is(equalTo(2))); assertThat(gemfireProperties.containsKey("disable-auto-reconnect"), is(true)); @@ -147,13 +143,15 @@ public class CacheFactoryBeanTest { } @Test - public void postProcessBeforeCacheInitializationWithAutoReconnectAndClusterConfigurationEnabled() { - Properties gemfireProperties = new Properties(); + public void applyCacheConfigurersWithAutoReconnectAndClusterConfigurationEnabled() { + CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); cacheFactoryBean.setEnableAutoReconnect(true); cacheFactoryBean.setUseClusterConfiguration(true); - cacheFactoryBean.postProcessBeforeCacheInitialization(gemfireProperties); + cacheFactoryBean.applyCacheConfigurers(); + + Properties gemfireProperties = cacheFactoryBean.getProperties(); assertThat(gemfireProperties.size(), is(equalTo(2))); assertThat(gemfireProperties.containsKey("disable-auto-reconnect"), is(true)); @@ -163,13 +161,15 @@ public class CacheFactoryBeanTest { } @Test - public void postProcessBeforeCacheInitializationWithAutoReconnectDisabledAndClusterConfigurationEnabled() { - Properties gemfireProperties = new Properties(); + public void applyCacheConfigurersWithAutoReconnectDisabledAndClusterConfigurationEnabled() { + CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); cacheFactoryBean.setEnableAutoReconnect(false); cacheFactoryBean.setUseClusterConfiguration(true); - cacheFactoryBean.postProcessBeforeCacheInitialization(gemfireProperties); + cacheFactoryBean.applyCacheConfigurers(); + + Properties gemfireProperties = cacheFactoryBean.getProperties(); assertThat(gemfireProperties.size(), is(equalTo(2))); assertThat(gemfireProperties.containsKey("disable-auto-reconnect"), is(true)); @@ -179,10 +179,29 @@ public class CacheFactoryBeanTest { } @Test - public void getObjectCallsInit() throws Exception { - final Cache mockCache = mock(Cache.class); + public void applyCacheConfigurersWithAutoReconnectEnabledAndClusterConfigurationDisabled() { - final AtomicBoolean initCalled = new AtomicBoolean(false); + CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); + + cacheFactoryBean.setEnableAutoReconnect(true); + cacheFactoryBean.setUseClusterConfiguration(false); + cacheFactoryBean.applyCacheConfigurers(); + + Properties gemfireProperties = cacheFactoryBean.getProperties(); + + assertThat(gemfireProperties.size(), is(equalTo(2))); + assertThat(gemfireProperties.containsKey("disable-auto-reconnect"), is(true)); + assertThat(gemfireProperties.containsKey("use-cluster-configuration"), is(true)); + assertThat(gemfireProperties.getProperty("disable-auto-reconnect"), is(equalTo("false"))); + assertThat(gemfireProperties.getProperty("use-cluster-configuration"), is(equalTo("false"))); + } + + @Test + public void getObjectCallsInit() throws Exception { + + AtomicBoolean initCalled = new AtomicBoolean(false); + + Cache mockCache = mock(Cache.class); CacheFactoryBean cacheFactoryBean = new CacheFactoryBean() { @Override Cache init() { @@ -199,6 +218,7 @@ public class CacheFactoryBeanTest { @Test public void getObjectReturnsExistingCache() throws Exception { + Cache mockCache = mock(Cache.class); CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); @@ -323,9 +343,11 @@ public class CacheFactoryBeanTest { @Test public void resolveCacheCallsFetchCacheReturnsMock() { - final Cache mockCache = mock(Cache.class); + + Cache mockCache = mock(Cache.class); CacheFactoryBean cacheFactoryBean = new CacheFactoryBean() { + @Override @SuppressWarnings("unchecked ") protected T fetchCache() { return (T) mockCache; @@ -339,8 +361,9 @@ public class CacheFactoryBeanTest { @Test public void resolveCacheCreatesCacheWhenFetchCacheThrowsCacheClosedException() { - final Cache mockCache = mock(Cache.class); - final CacheFactory mockCacheFactory = mock(CacheFactory.class); + + Cache mockCache = mock(Cache.class); + CacheFactory mockCacheFactory = mock(CacheFactory.class); when(mockCacheFactory.create()).thenReturn(mockCache); @@ -364,6 +387,7 @@ public class CacheFactoryBeanTest { @Test public void fetchExistingCache() throws Exception { + Cache mockCache = mock(Cache.class); CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); @@ -378,7 +402,9 @@ public class CacheFactoryBeanTest { @Test public void resolveProperties() { + Properties gemfireProperties = new Properties(); + CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); cacheFactoryBean.setProperties(gemfireProperties); @@ -388,6 +414,7 @@ public class CacheFactoryBeanTest { @Test public void resolvePropertiesWhenNull() { + CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); cacheFactoryBean.setProperties(null); @@ -400,7 +427,9 @@ public class CacheFactoryBeanTest { @Test public void createFactory() { + Properties gemfireProperties = new Properties(); + Object cacheFactoryReference = new CacheFactoryBean().createFactory(gemfireProperties); assertThat(cacheFactoryReference, is(instanceOf(CacheFactory.class))); @@ -416,9 +445,10 @@ public class CacheFactoryBeanTest { @Test public void prepareFactoryWithUnspecifiedPdxOptions() { + CacheFactory mockCacheFactory = mock(CacheFactory.class); - assertThat(new CacheFactoryBean().prepareFactory(mockCacheFactory), is(sameInstance(mockCacheFactory))); + assertThat(new CacheFactoryBean().configureFactory(mockCacheFactory), is(sameInstance(mockCacheFactory))); verify(mockCacheFactory, never()).setPdxDiskStore(any(String.class)); verify(mockCacheFactory, never()).setPdxIgnoreUnreadFields(any(Boolean.class)); @@ -429,6 +459,7 @@ public class CacheFactoryBeanTest { @Test public void prepareFactoryWithSpecificPdxOptions() { + CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); cacheFactoryBean.setPdxSerializer(mock(PdxSerializer.class)); @@ -437,7 +468,7 @@ public class CacheFactoryBeanTest { CacheFactory mockCacheFactory = mock(CacheFactory.class); - assertThat(cacheFactoryBean.prepareFactory(mockCacheFactory), is(sameInstance(mockCacheFactory))); + assertThat(cacheFactoryBean.configureFactory(mockCacheFactory), is(sameInstance(mockCacheFactory))); verify(mockCacheFactory, never()).setPdxDiskStore(any(String.class)); verify(mockCacheFactory, times(1)).setPdxIgnoreUnreadFields(eq(false)); @@ -448,6 +479,7 @@ public class CacheFactoryBeanTest { @Test public void prepareFactoryWithAllPdxOptions() { + CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); cacheFactoryBean.setPdxDiskStoreName("testPdxDiskStoreName"); @@ -458,7 +490,7 @@ public class CacheFactoryBeanTest { CacheFactory mockCacheFactory = mock(CacheFactory.class); - assertThat(cacheFactoryBean.prepareFactory(mockCacheFactory), is(sameInstance(mockCacheFactory))); + assertThat(cacheFactoryBean.configureFactory(mockCacheFactory), is(sameInstance(mockCacheFactory))); verify(mockCacheFactory, times(1)).setPdxDiskStore(eq("testPdxDiskStoreName")); verify(mockCacheFactory, times(1)).setPdxIgnoreUnreadFields(eq(false)); @@ -468,24 +500,8 @@ public class CacheFactoryBeanTest { } @Test - public void createCacheWithExistingCache() throws Exception { - CacheFactory mockCacheFactory = mock(CacheFactory.class); - CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); + public void createCacheWithCacheFactory() { - cacheFactoryBean.setCache(mockCache); - - assertThat(cacheFactoryBean.getCache(), is(sameInstance(mockCache))); - - Cache actualCache = cacheFactoryBean.createCache(mockCacheFactory); - - assertThat(actualCache, is(sameInstance(mockCache))); - - verify(mockCacheFactory, never()).create(); - verifyZeroInteractions(mockCache); - } - - @Test - public void createCacheWithNoExistingCache() { CacheFactory mockCacheFactory = mock(CacheFactory.class); when(mockCacheFactory.create()).thenReturn(mockCache); @@ -502,6 +518,7 @@ public class CacheFactoryBeanTest { @Test(expected = IllegalArgumentException.class) public void postProcessCacheWithInvalidCriticalHeapPercentage() throws Exception { + try { CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); @@ -521,6 +538,7 @@ public class CacheFactoryBeanTest { @Test(expected = IllegalArgumentException.class) public void postProcessCacheWithInvalidCriticalOffHeapPercentage() throws Exception { + try { CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); @@ -540,6 +558,7 @@ public class CacheFactoryBeanTest { @Test(expected = IllegalArgumentException.class) public void postProcessCacheWithInvalidEvictionHeapPercentage() throws Exception { + try { CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); @@ -559,6 +578,7 @@ public class CacheFactoryBeanTest { @Test(expected = IllegalArgumentException.class) public void postProcessCacheWithInvalidEvictionOffHeapPercentage() throws Exception { + try { CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); @@ -584,6 +604,7 @@ public class CacheFactoryBeanTest { @Test public void getObjectTypeWithExistingCache() { + Cache mockCache = mock(Cache.class); CacheFactoryBean cacheFactoryBean = new CacheFactoryBean(); @@ -600,8 +621,10 @@ public class CacheFactoryBeanTest { @Test @SuppressWarnings("unchecked") public void destroy() throws Exception { - final AtomicBoolean fetchCacheCalled = new AtomicBoolean(false); - final Cache mockCache = mock(Cache.class, "GemFireCache"); + + AtomicBoolean fetchCacheCalled = new AtomicBoolean(false); + + Cache mockCache = mock(Cache.class, "GemFireCache"); GemfireBeanFactoryLocator mockGemfireBeanFactoryLocator = mock(GemfireBeanFactoryLocator.class); @@ -631,7 +654,8 @@ public class CacheFactoryBeanTest { @Test @SuppressWarnings("unchecked") public void destroyWhenCacheIsNull() throws Exception { - final AtomicBoolean fetchCacheCalled = new AtomicBoolean(false); + + AtomicBoolean fetchCacheCalled = new AtomicBoolean(false); CacheFactoryBean cacheFactoryBean = new CacheFactoryBean() { @Override protected T fetchCache() { @@ -650,8 +674,10 @@ public class CacheFactoryBeanTest { @Test @SuppressWarnings("unchecked") public void destroyWhenCacheClosedIsTrue() throws Exception { - final AtomicBoolean fetchCacheCalled = new AtomicBoolean(false); - final Cache mockCache = mock(Cache.class, "GemFireCache"); + + AtomicBoolean fetchCacheCalled = new AtomicBoolean(false); + + Cache mockCache = mock(Cache.class, "GemFireCache"); CacheFactoryBean cacheFactoryBean = new CacheFactoryBean() { @Override @SuppressWarnings("unchecked") protected T fetchCache() { @@ -672,6 +698,7 @@ public class CacheFactoryBeanTest { @Test public void closeCache() { + GemFireCache mockCache = mock(GemFireCache.class, "testCloseCache.MockCache"); new CacheFactoryBean().close(mockCache); diff --git a/src/test/java/org/springframework/data/gemfire/CacheIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/CacheIntegrationTest.java index 8638a2d2..aaaa2446 100644 --- a/src/test/java/org/springframework/data/gemfire/CacheIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/CacheIntegrationTest.java @@ -25,7 +25,7 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; /** * Integration test trying various basic configurations of GemFire through @@ -36,21 +36,29 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * @author Costin Leau * @author John Blum */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration(locations = "basic-cache.xml") public class CacheIntegrationTest { - @Autowired ApplicationContext ctx; + @Autowired + ApplicationContext applicationContext; + Cache cache; + @After + public void tearDown() { + GemfireUtils.close(this.cache); + } + @Test public void testBasicCache() throws Exception { - cache = ctx.getBean("default-cache",Cache.class); + cache = applicationContext.getBean("default-cache",Cache.class); } @Test public void testCacheWithProps() throws Exception { - cache = ctx.getBean("cache-with-props", Cache.class); + cache = applicationContext.getBean("cache-with-props", Cache.class); + // the name property seems to be ignored assertEquals("cache-with-props", cache.getDistributedSystem().getName()); assertEquals("cache-with-props", cache.getName()); @@ -58,18 +66,15 @@ public class CacheIntegrationTest { @Test public void testNamedCache() throws Exception { - cache = ctx.getBean("named-cache", Cache.class); + + cache = applicationContext.getBean("named-cache", Cache.class); + assertEquals("named-cache", cache.getDistributedSystem().getName()); assertEquals("named-cache", cache.getName()); } @Test public void testCacheWithXml() throws Exception { - ctx.getBean("cache-with-xml", Cache.class); - } - - @After - public void tearDown() { - if (cache!=null) cache.close(); + applicationContext.getBean("cache-with-xml", Cache.class); } } diff --git a/src/test/java/org/springframework/data/gemfire/LookupRegionFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/LookupRegionFactoryBeanTest.java index 06ae0691..15901467 100644 --- a/src/test/java/org/springframework/data/gemfire/LookupRegionFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/LookupRegionFactoryBeanTest.java @@ -196,7 +196,7 @@ public class LookupRegionFactoryBeanTest { factoryBean.afterPropertiesSet(); } catch (IllegalStateException expected) { - assertEquals("Statistics for Region '/Example' must be enabled to change Entry & Region TTL/TTI Expiration settings", + assertEquals("Statistics for Region [/Example] must be enabled to change Entry & Region TTL/TTI Expiration settings", expected.getMessage()); throw expected; } diff --git a/src/test/java/org/springframework/data/gemfire/LookupRegionMutationIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/LookupRegionMutationIntegrationTest.java index f743bea9..5a37004b 100644 --- a/src/test/java/org/springframework/data/gemfire/LookupRegionMutationIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/LookupRegionMutationIntegrationTest.java @@ -51,7 +51,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.BeanNameAware; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.StringUtils; /** @@ -67,7 +67,7 @@ import org.springframework.util.StringUtils; * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner * @since 1.7.0 */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration @SuppressWarnings("unused") public class LookupRegionMutationIntegrationTest { @@ -75,7 +75,8 @@ public class LookupRegionMutationIntegrationTest { @Resource(name = "Example") private Region example; - protected void assertCacheListeners(CacheListener[] cacheListeners, Collection expectedCacheListenerNames) { + private void assertCacheListeners(CacheListener[] cacheListeners, Collection expectedCacheListenerNames) { + if (!expectedCacheListenerNames.isEmpty()) { assertNotNull("CacheListeners must not be null!", cacheListeners); assertEquals(expectedCacheListenerNames.size(), cacheListeners.length); @@ -83,38 +84,44 @@ public class LookupRegionMutationIntegrationTest { } } - protected void assertEvictionAttributes(EvictionAttributes evictionAttributes, EvictionAction expectedAction, EvictionAlgorithm expectedAlgorithm, int expectedMaximum) { + private void assertEvictionAttributes(EvictionAttributes evictionAttributes, EvictionAction expectedAction, + EvictionAlgorithm expectedAlgorithm, int expectedMaximum) { + assertNotNull("EvictionAttributes must not be null!", evictionAttributes); assertEquals(expectedAction, evictionAttributes.getAction()); assertEquals(expectedAlgorithm, evictionAttributes.getAlgorithm()); assertEquals(expectedMaximum, evictionAttributes.getMaximum()); } - protected void assertExpirationAttributes(ExpirationAttributes expirationAttributes, + private void assertExpirationAttributes(ExpirationAttributes expirationAttributes, + String description, int expectedTimeout, ExpirationAction expectedAction) { + assertNotNull(String.format("ExpirationAttributes for '%1$s' must not be null!", description), expirationAttributes); assertEquals(expectedAction, expirationAttributes.getAction()); assertEquals(expectedTimeout, expirationAttributes.getTimeout()); } - protected void assertGatewaySenders(Region region, List expectedGatewaySenderIds) { + private void assertGatewaySenders(Region region, List expectedGatewaySenderIds) { + assertNotNull(region.getAttributes()); assertNotNull(region.getAttributes().getGatewaySenderIds()); assertEquals(expectedGatewaySenderIds.size(), region.getAttributes().getGatewaySenderIds().size()); assertTrue(expectedGatewaySenderIds.containsAll(region.getAttributes().getGatewaySenderIds())); } - protected void assertGemFireComponent(Object gemfireComponent, String expectedName) { + private void assertGemFireComponent(Object gemfireComponent, String expectedName) { + assertNotNull("The GemFire component must not be null!", gemfireComponent); assertEquals(expectedName, gemfireComponent.toString()); } - protected void assertRegionAttributes(Region region, String expectedName, DataPolicy expectedDataPolicy) { + private void assertRegionAttributes(Region region, String expectedName, DataPolicy expectedDataPolicy) { assertRegionAttributes(region, expectedName, String.format("%1$s%2$s", Region.SEPARATOR, expectedName), expectedDataPolicy); } - protected void assertRegionAttributes(Region region, String expectedName, String expectedFullPath, + private void assertRegionAttributes(Region region, String expectedName, String expectedFullPath, DataPolicy expectedDataPolicy) { assertNotNull(String.format("'%1$s' Region was not properly initialized!", region)); @@ -124,7 +131,8 @@ public class LookupRegionMutationIntegrationTest { assertEquals(expectedDataPolicy, region.getAttributes().getDataPolicy()); } - protected Collection toStrings(Object[] objects) { + private Collection toStrings(Object[] objects) { + List cacheListenerNames = new ArrayList(objects.length); for (Object object : objects) { @@ -136,6 +144,7 @@ public class LookupRegionMutationIntegrationTest { @Test public void testRegionConfiguration() { + assertRegionAttributes(example, "Example", DataPolicy.REPLICATE); assertEquals(13, example.getAttributes().getInitialCapacity()); assertEquals(0.85f, example.getAttributes().getLoadFactor(), 0.0f); @@ -249,11 +258,12 @@ public class LookupRegionMutationIntegrationTest { public static final class TestCustomExpiry extends AbstractNameable implements CustomExpiry { - @Override public ExpirationAttributes getExpiry(Region.Entry entry) { + @Override + public ExpirationAttributes getExpiry(Region.Entry entry) { throw new UnsupportedOperationException("Not Implemented!"); } - @Override public void close() { } + @Override + public void close() { } } - } diff --git a/src/test/java/org/springframework/data/gemfire/LookupSubRegionTest.java b/src/test/java/org/springframework/data/gemfire/LookupSubRegionTest.java index a745d029..7b11ecf4 100644 --- a/src/test/java/org/springframework/data/gemfire/LookupSubRegionTest.java +++ b/src/test/java/org/springframework/data/gemfire/LookupSubRegionTest.java @@ -26,7 +26,7 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; /** * The LookupSubRegionTest class is a test suite of test cases testing the contract and functionality of Region lookups @@ -41,15 +41,16 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * @since 1.3.3 * @since 7.0.1 (GemFire) */ +@RunWith(SpringRunner.class) @ContextConfiguration("lookupSubRegion.xml") -@RunWith(SpringJUnit4ClassRunner.class) @SuppressWarnings("unused") public class LookupSubRegionTest { @Autowired - private ApplicationContext context; + private ApplicationContext applicationContext; + + private void assertRegionExists(final String expectedRegionName, final String expectedRegionPath, final Region region) { - protected void assertRegionExists(final String expectedRegionName, final String expectedRegionPath, final Region region) { assertNotNull(String.format("The Region with name (%1$s) at path (%2$s) was null!", expectedRegionName, expectedRegionPath), region); assertEquals(String.format("Expected Region name of %1$s; but was %2$s!", expectedRegionName, region.getName()), @@ -60,37 +61,38 @@ public class LookupSubRegionTest { @Test public void testDirectLookup() { - Region accounts = context.getBean("/Customers/Accounts", Region.class); + + Region accounts = applicationContext.getBean("/Customers/Accounts", Region.class); assertRegionExists("Accounts", "/Customers/Accounts", accounts); - assertFalse(context.containsBean("Customers/Accounts")); - assertFalse(context.containsBean("/Customers")); - assertFalse(context.containsBean("Customers")); + assertFalse(applicationContext.containsBean("Customers/Accounts")); + assertFalse(applicationContext.containsBean("/Customers")); + assertFalse(applicationContext.containsBean("Customers")); - Region items = context.getBean("Customers/Accounts/Orders/Items", Region.class); + Region items = applicationContext.getBean("Customers/Accounts/Orders/Items", Region.class); assertRegionExists("Items", "/Customers/Accounts/Orders/Items", items); - assertFalse(context.containsBean("/Customers/Accounts/Orders/Items")); - assertFalse(context.containsBean("/Customers/Accounts/Orders")); - assertFalse(context.containsBean("Customers/Accounts/Orders")); + assertFalse(applicationContext.containsBean("/Customers/Accounts/Orders/Items")); + assertFalse(applicationContext.containsBean("/Customers/Accounts/Orders")); + assertFalse(applicationContext.containsBean("Customers/Accounts/Orders")); } @Test public void testNestedLookup() { - Region parent = context.getBean("Parent", Region.class); + + Region parent = applicationContext.getBean("Parent", Region.class); assertRegionExists("Parent", "/Parent", parent); - assertFalse(context.containsBean("/Parent")); + assertFalse(applicationContext.containsBean("/Parent")); - Region child = context.getBean("/Parent/Child", Region.class); + Region child = applicationContext.getBean("/Parent/Child", Region.class); assertRegionExists("Child", "/Parent/Child", child); - assertFalse(context.containsBean("Parent/Child")); + assertFalse(applicationContext.containsBean("Parent/Child")); - Region grandchild = context.getBean("/Parent/Child/Grandchild", Region.class); + Region grandchild = applicationContext.getBean("/Parent/Child/Grandchild", Region.class); assertRegionExists("Grandchild", "/Parent/Child/Grandchild", grandchild); - assertFalse(context.containsBean("Parent/Child/Grandchild")); + assertFalse(applicationContext.containsBean("Parent/Child/Grandchild")); } - } diff --git a/src/test/java/org/springframework/data/gemfire/PartitionedRegionFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/PartitionedRegionFactoryBeanTest.java index 37eb7b26..2aee3f19 100644 --- a/src/test/java/org/springframework/data/gemfire/PartitionedRegionFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/PartitionedRegionFactoryBeanTest.java @@ -169,7 +169,7 @@ public class PartitionedRegionFactoryBeanTest { factoryBean.resolveDataPolicy(mockRegionFactory, true, "PARTITION"); } catch (IllegalArgumentException e) { - assertEquals("Data Policy [PARTITION] is invalid when persistent is true.", e.getMessage()); + assertEquals("Data Policy [PARTITION] is not valid when persistent is true", e.getMessage()); throw e; } finally { @@ -195,7 +195,7 @@ public class PartitionedRegionFactoryBeanTest { factoryBean.resolveDataPolicy(mockRegionFactory, false, "PERSISTENT_PARTITION"); } catch (IllegalArgumentException e) { - assertEquals("Data Policy [PERSISTENT_PARTITION] is invalid when persistent is false.", e.getMessage()); + assertEquals("Data Policy [PERSISTENT_PARTITION] is not valid when persistent is false", e.getMessage()); throw e; } finally { diff --git a/src/test/java/org/springframework/data/gemfire/RegionFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/RegionFactoryBeanTest.java index 836e0157..b52ebbf3 100644 --- a/src/test/java/org/springframework/data/gemfire/RegionFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/RegionFactoryBeanTest.java @@ -125,7 +125,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { @Override public void verify() { assertNotNull(this.exception); - assertEquals("Data Policy [PERSISTENT_REPLICATE] is invalid when persistent is false.", + assertEquals("Data Policy [PERSISTENT_REPLICATE] is not valid when persistent is false", exception.getMessage()); } }; @@ -170,53 +170,6 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { return new TestRegionFactory(); } - @Test - public void testAssertDataPolicyAndPersistentAttributesAreCompatible() { - - RegionFactoryBean factoryBean = new TestRegionFactoryBean<>(); - - factoryBean.setPersistent(null); - factoryBean.assertDataPolicyAndPersistentAttributesAreCompatible(DataPolicy.PARTITION); - factoryBean.assertDataPolicyAndPersistentAttributesAreCompatible(DataPolicy.REPLICATE); - factoryBean.assertDataPolicyAndPersistentAttributesAreCompatible(DataPolicy.PERSISTENT_PARTITION); - factoryBean.assertDataPolicyAndPersistentAttributesAreCompatible(DataPolicy.PERSISTENT_REPLICATE); - factoryBean.setPersistent(false); - factoryBean.assertDataPolicyAndPersistentAttributesAreCompatible(DataPolicy.PARTITION); - factoryBean.assertDataPolicyAndPersistentAttributesAreCompatible(DataPolicy.REPLICATE); - factoryBean.setPersistent(true); - factoryBean.assertDataPolicyAndPersistentAttributesAreCompatible(DataPolicy.PERSISTENT_PARTITION); - factoryBean.assertDataPolicyAndPersistentAttributesAreCompatible(DataPolicy.PERSISTENT_REPLICATE); - } - - @Test(expected = IllegalArgumentException.class) - public void testAssertNonPersistentDataPolicyWithPersistentAttribute() { - - try { - RegionFactoryBean factoryBean = new TestRegionFactoryBean<>(); - factoryBean.setPersistent(true); - factoryBean.assertDataPolicyAndPersistentAttributesAreCompatible(DataPolicy.REPLICATE); - } - catch (IllegalArgumentException expected) { - assertEquals("Data Policy [REPLICATE] is invalid when persistent is true.", expected.getMessage()); - throw expected; - } - } - - @Test(expected = IllegalArgumentException.class) - public void testAssertPersistentDataPolicyWithNonPersistentAttribute() { - - try { - RegionFactoryBean factoryBean = new TestRegionFactoryBean<>(); - factoryBean.setPersistent(false); - factoryBean.assertDataPolicyAndPersistentAttributesAreCompatible(DataPolicy.PERSISTENT_PARTITION); - } - catch (IllegalArgumentException expected) { - assertEquals("Data Policy [PERSISTENT_PARTITION] is invalid when persistent is false.", - expected.getMessage()); - throw expected; - } - } - @Test public void testIsPersistent() { @@ -233,26 +186,6 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { assertTrue(factoryBean.isPersistent()); } - @Test - public void testIsPersistentUnspecified() { - - RegionFactoryBean factoryBean = new TestRegionFactoryBean<>(); - - assertTrue(factoryBean.isPersistentUnspecified()); - - factoryBean.setPersistent(false); - - assertFalse(factoryBean.isPersistentUnspecified()); - - factoryBean.setPersistent(true); - - assertFalse(factoryBean.isPersistentUnspecified()); - - factoryBean.setPersistent(null); - - assertTrue(factoryBean.isPersistentUnspecified()); - } - @Test public void testIsNotPersistent() { @@ -761,7 +694,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { factoryBean.resolveDataPolicy(mockRegionFactory, true, " "); } catch (IllegalArgumentException expected) { - assertEquals("Data Policy [ ] is invalid.", expected.getMessage()); + assertEquals("Data Policy [ ] is invalid", expected.getMessage()); throw expected; } finally { @@ -781,7 +714,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { factoryBean.resolveDataPolicy(mockRegionFactory, true, ""); } catch (IllegalArgumentException expected) { - assertEquals("Data Policy [] is invalid.", expected.getMessage()); + assertEquals("Data Policy [] is invalid", expected.getMessage()); throw expected; } finally { @@ -801,7 +734,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { factoryBean.resolveDataPolicy(mockRegionFactory, true, "CSV"); } catch (IllegalArgumentException expected) { - assertEquals("Data Policy [CSV] is invalid.", expected.getMessage()); + assertEquals("Data Policy [CSV] is invalid", expected.getMessage()); throw expected; } finally { @@ -842,7 +775,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { factoryBean.resolveDataPolicy(mockRegionFactory, true, "EMPTY"); } catch (IllegalArgumentException expected) { - assertEquals("Data Policy [EMPTY] is invalid when persistent is true.", expected.getMessage()); + assertEquals("Data Policy [EMPTY] is not valid when persistent is true", expected.getMessage()); throw expected; } finally { @@ -883,7 +816,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { factoryBean.resolveDataPolicy(mockRegionFactory, false, "PERSISTENT_PARTITION"); } catch (IllegalArgumentException expected) { - assertEquals("Data Policy [PERSISTENT_PARTITION] is invalid when persistent is false.", expected.getMessage()); + assertEquals("Data Policy [PERSISTENT_PARTITION] is not valid when persistent is false", expected.getMessage()); throw expected; } finally { @@ -906,7 +839,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { "Setting the 'persistent' attribute to TRUE and 'Data Policy' to PARTITION should have thrown an IllegalArgumentException!"); } catch (IllegalArgumentException expected) { - assertEquals("Data Policy [PARTITION] is invalid when persistent is true.", expected.getMessage()); + assertEquals("Data Policy [PARTITION] is not valid when persistent is true", expected.getMessage()); throw expected; } finally { @@ -992,7 +925,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { factoryBean.resolveDataPolicy(mockRegionFactory, false, (String) null); } catch (IllegalArgumentException expected) { - assertEquals("Data Policy [PERSISTENT_PARTITION] is invalid when persistent is false.", expected.getMessage()); + assertEquals("Data Policy [PERSISTENT_PARTITION] is not valid when persistent is false", expected.getMessage()); throw expected; } finally { @@ -1014,7 +947,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { factoryBean.resolveDataPolicy(mockRegionFactory, true, (String) null); } catch (IllegalArgumentException expected) { - assertEquals("Data Policy [PARTITION] is invalid when persistent is true.", expected.getMessage()); + assertEquals("Data Policy [PARTITION] is not valid when persistent is true", expected.getMessage()); throw expected; } finally { @@ -1092,7 +1025,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { fail("Setting the 'persistent' attribute to FALSE and 'Data Policy' to PERSISTENT_REPLICATE should have thrown an IllegalArgumentException!"); } catch (IllegalArgumentException expected) { - assertEquals("Data Policy [PERSISTENT_REPLICATE] is invalid when persistent is false.", expected.getMessage()); + assertEquals("Data Policy [PERSISTENT_REPLICATE] is not valid when persistent is false", expected.getMessage()); throw expected; } finally { @@ -1114,7 +1047,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests { fail("Setting the 'persistent' attribute to TRUE and 'Data Policy' to REPLICATE should have thrown an IllegalArgumentException!"); } catch (IllegalArgumentException expected) { - assertEquals("Data Policy [REPLICATE] is invalid when persistent is true.", expected.getMessage()); + assertEquals("Data Policy [REPLICATE] is not valid when persistent is true", expected.getMessage()); throw expected; } finally { diff --git a/src/test/java/org/springframework/data/gemfire/RegionLookupIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/RegionLookupIntegrationTests.java index 27cf70fc..7d88888f 100644 --- a/src/test/java/org/springframework/data/gemfire/RegionLookupIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/RegionLookupIntegrationTests.java @@ -22,6 +22,8 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.util.Optional; + import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionExistsException; @@ -44,9 +46,11 @@ import org.springframework.data.gemfire.fork.SpringContainerProcess; * @since 1.4.0 * @link https://jira.spring.io/browse/SGF-204 */ +// TODO: slow test; can this test use mocks? public class RegionLookupIntegrationTests { - protected void assertNoRegionLookup(final String configLocation) { + private void assertNoRegionLookup(String configLocation) { + ConfigurableApplicationContext applicationContext = null; try { @@ -54,8 +58,9 @@ public class RegionLookupIntegrationTests { fail("Spring ApplicationContext should have thrown a BeanCreationException caused by a RegionExistsException!"); } catch (BeanCreationException expected) { - //expected.printStackTrace(System.err); + assertTrue(expected.getMessage(), expected.getCause() instanceof RegionExistsException); + throw (RegionExistsException) expected.getCause(); } finally { @@ -63,18 +68,17 @@ public class RegionLookupIntegrationTests { } } - protected void closeApplicationContext(final ConfigurableApplicationContext applicationContext) { - if (applicationContext != null) { - applicationContext.close(); - } + private ConfigurableApplicationContext createApplicationContext(String configLocation) { + return new ClassPathXmlApplicationContext(configLocation); } - protected ConfigurableApplicationContext createApplicationContext(final String configLocation) { - return new ClassPathXmlApplicationContext(configLocation); + private void closeApplicationContext(ConfigurableApplicationContext applicationContext) { + Optional.ofNullable(applicationContext).ifPresent(ConfigurableApplicationContext::close); } @Test public void testAllowRegionBeanDefinitionOverrides() { + ConfigurableApplicationContext applicationContext = null; try { @@ -142,6 +146,7 @@ public class RegionLookupIntegrationTests { @Test public void testEnableRegionLookups() { + ConfigurableApplicationContext applicationContext = null; try { @@ -225,6 +230,7 @@ public class RegionLookupIntegrationTests { @Test public void testEnableClientRegionLookups() { + ConfigurableApplicationContext applicationContext = null; try { @@ -257,5 +263,4 @@ public class RegionLookupIntegrationTests { closeApplicationContext(applicationContext); } } - } diff --git a/src/test/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBeanTest.java index 10af6123..d2f97ee0 100644 --- a/src/test/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBeanTest.java @@ -168,7 +168,7 @@ public class ReplicatedRegionFactoryBeanTest { factoryBean.resolveDataPolicy(mockRegionFactory, true, "empty"); } catch (IllegalArgumentException e) { - assertEquals("Data Policy [EMPTY] is invalid when persistent is true.", e.getMessage()); + assertEquals("Data Policy [EMPTY] is not valid when persistent is true", e.getMessage()); throw e; } finally { @@ -202,7 +202,7 @@ public class ReplicatedRegionFactoryBeanTest { factoryBean.resolveDataPolicy(mockRegionFactory, true, "REPLICATE"); } catch (IllegalArgumentException e) { - assertEquals("Data Policy [REPLICATE] is invalid when persistent is true.", e.getMessage()); + assertEquals("Data Policy [REPLICATE] is not valid when persistent is true", e.getMessage()); throw e; } finally { @@ -228,7 +228,7 @@ public class ReplicatedRegionFactoryBeanTest { factoryBean.resolveDataPolicy(mockRegionFactory, false, "PERSISTENT_REPLICATE"); } catch (IllegalArgumentException e) { - assertEquals("Data Policy [PERSISTENT_REPLICATE] is invalid when persistent is false.", e.getMessage()); + assertEquals("Data Policy [PERSISTENT_REPLICATE] is not valid when persistent is false", e.getMessage()); throw e; } finally { diff --git a/src/test/java/org/springframework/data/gemfire/client/ClientCacheFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/client/ClientCacheFactoryBeanTest.java index 7fd388ca..4e02b551 100644 --- a/src/test/java/org/springframework/data/gemfire/client/ClientCacheFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/ClientCacheFactoryBeanTest.java @@ -32,6 +32,7 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; @@ -40,7 +41,6 @@ import static org.mockito.Mockito.when; import java.net.InetSocketAddress; import java.util.Arrays; import java.util.Collections; -import java.util.Map; import java.util.Optional; import java.util.Properties; import java.util.concurrent.atomic.AtomicBoolean; @@ -52,14 +52,10 @@ import org.apache.geode.cache.client.ClientCacheFactory; import org.apache.geode.cache.client.Pool; import org.apache.geode.distributed.DistributedSystem; import org.apache.geode.pdx.PdxSerializer; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.data.gemfire.GemfireUtils; -import org.springframework.data.gemfire.config.xml.GemfireConstants; import org.springframework.data.gemfire.support.ConnectionEndpoint; import org.springframework.data.gemfire.util.ArrayUtils; import org.springframework.data.gemfire.util.DistributedSystemUtils; @@ -84,17 +80,16 @@ import org.springframework.data.gemfire.util.DistributedSystemUtils; */ public class ClientCacheFactoryBeanTest { - @Rule - public ExpectedException exception = ExpectedException.none(); - private Properties createProperties(String key, String value) { return addProperty(null, key, value); } @SuppressWarnings("all") private Properties addProperty(Properties properties, String key, String value) { + properties = Optional.ofNullable(properties).orElseGet(Properties::new); properties.setProperty(key, value); + return properties; } @@ -267,19 +262,19 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean() { @Override - ClientCacheFactory initializePdx(ClientCacheFactory clientCacheFactory) { + ClientCacheFactory configurePdx(ClientCacheFactory clientCacheFactory) { initializePdxCalled.set(true); return clientCacheFactory; } @Override - ClientCacheFactory initializePool(final ClientCacheFactory clientCacheFactory) { + ClientCacheFactory configurePool(final ClientCacheFactory clientCacheFactory) { initializePoolCalled.set(true); return clientCacheFactory; } }; - assertThat(clientCacheFactoryBean.prepareFactory(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configureFactory(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); assertThat(initializePdxCalled.get(), is(true)); assertThat(initializePoolCalled.get(), is(true)); @@ -306,7 +301,7 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class); - assertThat(clientCacheFactoryBean.initializePdx(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configurePdx(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); verify(mockClientCacheFactory, times(1)).setPdxSerializer(eq(mockPdxSerializer)); @@ -332,7 +327,7 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class); - assertThat(clientCacheFactoryBean.initializePdx(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configurePdx(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); verify(mockClientCacheFactory, never()).setPdxDiskStore(anyString()); @@ -355,7 +350,7 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class); - assertThat(clientCacheFactoryBean.initializePdx(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configurePdx(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); verifyZeroInteractions(mockClientCacheFactory); @@ -419,7 +414,7 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class); - assertThat(clientCacheFactoryBean.initializePool(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configurePool(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); verify(mockPool, times(1)).getFreeConnectionTimeout(); @@ -523,7 +518,7 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class); - assertThat(clientCacheFactoryBean.initializePool(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configurePool(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); verifyZeroInteractions(mockPool); @@ -622,7 +617,7 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class); - assertThat(clientCacheFactoryBean.initializePool(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configurePool(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); verify(mockPool, times(1)).getFreeConnectionTimeout(); @@ -687,7 +682,7 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class); - assertThat(clientCacheFactoryBean.initializePool(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configurePool(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); verify(mockPool, never()).getLocators(); @@ -715,7 +710,7 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class); - assertThat(clientCacheFactoryBean.initializePool(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configurePool(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); verify(mockPool, never()).getLocators(); @@ -742,7 +737,7 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class); - assertThat(clientCacheFactoryBean.initializePool(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configurePool(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); verify(mockPool, times(1)).getLocators(); @@ -769,7 +764,7 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class); - assertThat(clientCacheFactoryBean.initializePool(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configurePool(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); verify(mockPool, never()).getLocators(); @@ -793,7 +788,7 @@ public class ClientCacheFactoryBeanTest { ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class); - assertThat(clientCacheFactoryBean.initializePool(mockClientCacheFactory), + assertThat(clientCacheFactoryBean.configurePool(mockClientCacheFactory), is(sameInstance(mockClientCacheFactory))); verify(mockClientCacheFactory, never()).addPoolLocator(anyString(), anyInt()); @@ -819,31 +814,29 @@ public class ClientCacheFactoryBeanTest { } @Test - public void resolvePoolByReturningProvidedPool() { + public void resolvePoolReturnsConfiguredPool() { Pool mockPool = mock(Pool.class); - ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); + ClientCacheFactoryBean clientCacheFactoryBean = spy(new ClientCacheFactoryBean()); clientCacheFactoryBean.setPool(mockPool); assertThat(clientCacheFactoryBean.getPool(), is(sameInstance(mockPool))); assertThat(clientCacheFactoryBean.resolvePool(), is(equalTo(mockPool))); + verify(clientCacheFactoryBean, never()).getPoolName(); verifyZeroInteractions(mockPool); } @Test - public void resolvesPoolByName() { + public void resolvesPoolReturnsNamedPool() { Pool mockPool = mock(Pool.class); - ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean() { - @Override Pool findPool(String name) { - assertThat(name, is(equalTo("TestPool"))); - return mockPool; - } - }; + ClientCacheFactoryBean clientCacheFactoryBean = spy(new ClientCacheFactoryBean()); + + when(clientCacheFactoryBean.findPool(eq("TestPool"))).thenReturn(mockPool); clientCacheFactoryBean.setPoolName("TestPool"); @@ -851,150 +844,59 @@ public class ClientCacheFactoryBeanTest { assertThat(clientCacheFactoryBean.getPoolName(), is(equalTo("TestPool"))); assertThat(clientCacheFactoryBean.resolvePool(), is(equalTo(mockPool))); + verify(clientCacheFactoryBean, times(1)).findPool(eq("TestPool")); verifyZeroInteractions(mockPool); } @Test - public void resolvesPoolByDefaultName() { - - Pool mockPool = mock(Pool.class); - - ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean() { - @Override Pool findPool(String name) { - assertThat(name, is(equalTo(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME))); - return mockPool; - } - }; - - assertThat(clientCacheFactoryBean.getPool(), is(nullValue())); - assertThat(clientCacheFactoryBean.getPoolName(), is(nullValue())); - assertThat(clientCacheFactoryBean.resolvePool(), is(equalTo(mockPool))); - - verifyZeroInteractions(mockPool); - } - - @Test - public void resolvesNamedPoolFromBeanFactory() { - - ListableBeanFactory mockBeanFactory = mock(ListableBeanFactory.class); - - Pool mockPool = mock(Pool.class); - - PoolFactoryBean mockPoolFactoryBean = mock(PoolFactoryBean.class); - - Map beans = Collections.singletonMap("&TestPool", mockPoolFactoryBean); - - when(mockBeanFactory.getBeansOfType(eq(PoolFactoryBean.class), eq(false), eq(false))).thenReturn(beans); - when(mockPoolFactoryBean.getPool()).thenReturn(mockPool); - - ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); - - clientCacheFactoryBean.setBeanFactory(mockBeanFactory); - clientCacheFactoryBean.setPoolName("TestPool"); - - assertThat(clientCacheFactoryBean.getBeanFactory(), is(equalTo(mockBeanFactory))); - assertThat(clientCacheFactoryBean.getPool(), is(nullValue())); - assertThat(clientCacheFactoryBean.getPoolName(), is(equalTo("TestPool"))); - assertThat(clientCacheFactoryBean.resolvePool(), is(equalTo(mockPool))); - - verify(mockBeanFactory, times(1)).getBeansOfType(eq(PoolFactoryBean.class), eq(false), eq(false)); - verify(mockPoolFactoryBean, times(1)).getPool(); - verifyZeroInteractions(mockPool); - } - - @Test - public void resolvesUnnamedPoolFromBeanFactory() { - - ListableBeanFactory mockBeanFactory = mock(ListableBeanFactory.class); - - Pool mockPool = mock(Pool.class); - - PoolFactoryBean mockPoolFactoryBean = mock(PoolFactoryBean.class); - - Map beans = Collections.singletonMap("&gemfirePool", mockPoolFactoryBean); - - when(mockBeanFactory.getBeansOfType(eq(PoolFactoryBean.class), eq(false), eq(false))).thenReturn(beans); - when(mockPoolFactoryBean.getPool()).thenReturn(mockPool); - - ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); - - clientCacheFactoryBean.setBeanFactory(mockBeanFactory); - - assertThat(clientCacheFactoryBean.getBeanFactory(), is(equalTo(mockBeanFactory))); - assertThat(clientCacheFactoryBean.getPool(), is(nullValue())); - assertThat(clientCacheFactoryBean.getPoolName(), is(nullValue())); - assertThat(clientCacheFactoryBean.resolvePool(), is(equalTo(mockPool))); - - verify(mockBeanFactory, times(1)).getBeansOfType(eq(PoolFactoryBean.class), eq(false), eq(false)); - verify(mockPoolFactoryBean, times(1)).getPool(); - verifyZeroInteractions(mockPool); - } - - @Test - public void resolvePoolReturnsNullWhenNoBeansOfTypePoolFactoryBeanExists() { - - ListableBeanFactory mockBeanFactory = mock(ListableBeanFactory.class); - - Map beans = Collections.emptyMap(); - - when(mockBeanFactory.getBeansOfType(eq(PoolFactoryBean.class), eq(false), eq(false))).thenReturn(beans); - - ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); - - clientCacheFactoryBean.setBeanFactory(mockBeanFactory); - - assertThat(clientCacheFactoryBean.getBeanFactory(), is(equalTo(mockBeanFactory))); - assertThat(clientCacheFactoryBean.getPool(), is(nullValue())); - assertThat(clientCacheFactoryBean.getPoolName(), is(nullValue())); - assertThat(clientCacheFactoryBean.resolvePool(), is(nullValue())); - - verify(mockBeanFactory, times(1)).getBeansOfType(eq(PoolFactoryBean.class), eq(false), eq(false)); - } - - @Test - public void resolvePoolReturnsNullWhenNoBeansOfTypePoolFactoryBeanExistsWithPoolName() { - - ListableBeanFactory mockBeanFactory = mock(ListableBeanFactory.class); - - Pool mockPool = mock(Pool.class); - - PoolFactoryBean mockPoolFactoryBean = mock(PoolFactoryBean.class); - - Map beans = Collections.singletonMap("&swimPool", mockPoolFactoryBean); - - when(mockBeanFactory.getBeansOfType(eq(PoolFactoryBean.class), eq(false), eq(false))).thenReturn(beans); - when(mockPoolFactoryBean.getPool()).thenReturn(mockPool); - - ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); - - clientCacheFactoryBean.setBeanFactory(mockBeanFactory); - clientCacheFactoryBean.setPoolName("TestPool"); - - assertThat(clientCacheFactoryBean.getBeanFactory(), is(equalTo(mockBeanFactory))); - assertThat(clientCacheFactoryBean.getPool(), is(nullValue())); - assertThat(clientCacheFactoryBean.getPoolName(), is(equalTo("TestPool"))); - assertThat(clientCacheFactoryBean.resolvePool(), is(nullValue())); - - verify(mockBeanFactory, times(1)).getBeansOfType(eq(PoolFactoryBean.class), eq(false), eq(false)); - verify(mockPoolFactoryBean, never()).getPool(); - verifyZeroInteractions(mockPool); - } - - @Test - public void resolvePoolReturnsNullWhenBeanFactoryIsNotAListableBeanFactory() { + public void resolvesPoolReturnsNamedPoolFromBeanFactory() { BeanFactory mockBeanFactory = mock(BeanFactory.class); + Pool mockPool = mock(Pool.class); + + PoolFactoryBean mockPoolFactoryBean = mock(PoolFactoryBean.class); + + when(mockBeanFactory.containsBean(eq("TestPool"))).thenReturn(true); + when(mockBeanFactory.getBean(eq("&TestPool"), eq(PoolFactoryBean.class))).thenReturn(mockPoolFactoryBean); + when(mockPoolFactoryBean.getPool()).thenReturn(mockPool); + ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); clientCacheFactoryBean.setBeanFactory(mockBeanFactory); + clientCacheFactoryBean.setPoolName("TestPool"); assertThat(clientCacheFactoryBean.getBeanFactory(), is(equalTo(mockBeanFactory))); assertThat(clientCacheFactoryBean.getPool(), is(nullValue())); - assertThat(clientCacheFactoryBean.getPoolName(), is(nullValue())); - assertThat(clientCacheFactoryBean.resolvePool(), is(nullValue())); + assertThat(clientCacheFactoryBean.getPoolName(), is(equalTo("TestPool"))); + assertThat(clientCacheFactoryBean.resolvePool(), is(equalTo(mockPool))); - verifyZeroInteractions(mockBeanFactory); + verify(mockBeanFactory, times(1)).containsBean(eq("TestPool")); + verify(mockBeanFactory, times(1)) + .getBean(eq("&TestPool"), eq(PoolFactoryBean.class)); + verify(mockPoolFactoryBean, times(1)).getPool(); + verifyZeroInteractions(mockPool); + } + + @Test + public void resolvePoolWhenBeanFactoryHasNoPoolBeansReturnsNull() { + + BeanFactory mockBeanFactory = mock(BeanFactory.class); + + when(mockBeanFactory.containsBean(anyString())).thenReturn(false); + + ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); + + clientCacheFactoryBean.setBeanFactory(mockBeanFactory); + clientCacheFactoryBean.setPoolName("TestPool"); + + assertThat(clientCacheFactoryBean.getBeanFactory(), is(equalTo(mockBeanFactory))); + assertThat(clientCacheFactoryBean.getPool(), is(nullValue())); + assertThat(clientCacheFactoryBean.getPoolName(), is(equalTo("TestPool"))); + assertThat(clientCacheFactoryBean.resolvePool(), is(nullValue(Pool.class))); + + verify(mockBeanFactory, times(1)).containsBean(eq("TestPool")); + verify(mockBeanFactory, never()).getBean(anyString(), eq(PoolFactoryBean.class)); } @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 96ba8589..547b2644 100644 --- a/src/test/java/org/springframework/data/gemfire/client/ClientRegionFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/ClientRegionFactoryBeanTest.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.data.gemfire.client; import static org.assertj.core.api.Assertions.assertThat; @@ -20,13 +21,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; 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.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -51,10 +50,8 @@ import org.apache.geode.compression.Compressor; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.mockito.InOrder; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanFactory; -import org.springframework.core.io.Resource; import org.springframework.data.gemfire.TestUtils; import org.springframework.data.gemfire.util.ArrayUtils; @@ -79,32 +76,36 @@ public class ClientRegionFactoryBeanTest { @Before public void setup() { - factoryBean = spy(new ClientRegionFactoryBean<>()); + this.factoryBean = spy(new ClientRegionFactoryBean<>()); } @After public void tearDown() throws Exception { - factoryBean.destroy(); - factoryBean = null; + this.factoryBean.destroy(); + this.factoryBean = null; } @Test @SuppressWarnings({ "deprecation", "unchecked" }) public void createRegionUsingDefaultShortcut() throws Exception { - String testRegionName = "TestRegion"; + BeanFactory mockBeanFactory = mock(BeanFactory.class); ClientCache mockClientCache = mock(ClientCache.class); ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); + Pool mockPool = mock(Pool.class); + Region mockRegion = mock(Region.class); RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); + when(mockBeanFactory.getBean(eq("TestPoolTwo"), eq(Pool.class))).thenReturn(mockPool); when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.LOCAL))) .thenReturn(mockClientRegionFactory); - when(mockClientRegionFactory.create(eq(testRegionName))).thenReturn(mockRegion); + when(mockClientRegionFactory.create(eq("TestRegion"))).thenReturn(mockRegion); + when(mockPool.getName()).thenReturn("TestPoolTwo"); when(mockRegionAttributes.getCloningEnabled()).thenReturn(false); when(mockRegionAttributes.getCompressor()).thenReturn(mock(Compressor.class)); when(mockRegionAttributes.getConcurrencyChecksEnabled()).thenReturn(true); @@ -125,19 +126,6 @@ public class ClientRegionFactoryBeanTest { 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.containsBean(eq("TestPoolOne"))).thenReturn(false); - when(mockBeanFactory.containsBean(eq("TestPoolTwo"))).thenReturn(true); - 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)); - EvictionAttributes evictionAttributes = EvictionAttributes.createLRUEntryAttributes(); factoryBean.setAttributes(mockRegionAttributes); @@ -146,12 +134,11 @@ public class ClientRegionFactoryBeanTest { factoryBean.setEvictionAttributes(evictionAttributes); factoryBean.setPersistent(false); factoryBean.setPoolName("TestPoolTwo"); - factoryBean.setSnapshot(mockSnapshot); factoryBean.setShortcut(null); - Region actualRegion = factoryBean.createRegion(mockClientCache, testRegionName); + Region actualRegion = factoryBean.createRegion(mockClientCache, "TestRegion"); - assertSame(mockRegion, actualRegion); + assertThat(actualRegion).isEqualTo(mockRegion); verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.LOCAL)); verify(mockClientRegionFactory, times(1)).setCloningEnabled(eq(false)); @@ -161,6 +148,7 @@ public class ClientRegionFactoryBeanTest { verify(mockClientRegionFactory, times(1)).setCustomEntryIdleTimeout(null); verify(mockClientRegionFactory, times(1)).setCustomEntryTimeToLive(null); verify(mockClientRegionFactory, times(1)).setDiskStoreName(eq("TestDiskStoreOne")); + verify(mockClientRegionFactory, times(1)).setDiskStoreName(eq("TestDiskStoreTwo")); verify(mockClientRegionFactory, times(1)).setDiskSynchronous(eq(false)); verify(mockClientRegionFactory, times(1)).setEntryIdleTimeout(any(ExpirationAttributes.class)); verify(mockClientRegionFactory, times(1)).setEntryTimeToLive(any(ExpirationAttributes.class)); @@ -169,13 +157,12 @@ public class ClientRegionFactoryBeanTest { verify(mockClientRegionFactory, times(1)).setKeyConstraint(eq(Long.class)); verify(mockClientRegionFactory, times(1)).setLoadFactor(eq(0.75f)); verify(mockClientRegionFactory, never()).setPoolName(eq("TestPoolOne")); + verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPoolTwo")); 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)).setDiskStoreName(eq("TestDiskStoreTwo")); - verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPoolTwo")); - verify(mockClientRegionFactory, times(1)).create(eq(testRegionName)); + verify(mockClientRegionFactory, times(1)).create(eq("TestRegion")); verify(mockRegion, never()).loadSnapshot(any(InputStream.class)); } @@ -183,34 +170,37 @@ public class ClientRegionFactoryBeanTest { @SuppressWarnings({ "deprecation", "unchecked" }) public void createRegionUsingDefaultPersistentShortcut() throws Exception { + BeanFactory mockBeanFactory = mock(BeanFactory.class); + ClientCache mockClientCache = mock(ClientCache.class); ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); + Pool mockPool = mock(Pool.class); + Region mockRegion = mock(Region.class); + RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); + + when(mockBeanFactory.getBean(anyString(), eq(Pool.class))).thenReturn(mockPool); when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.LOCAL_PERSISTENT))) .thenReturn(mockClientRegionFactory); when(mockClientRegionFactory.create(eq("TestRegion"))).thenReturn(mockRegion); + when(mockRegionAttributes.getPoolName()).thenReturn("TestPool"); - BeanFactory mockBeanFactory = mock(BeanFactory.class); - - when(mockBeanFactory.containsBean(eq("TestPool"))).thenReturn(true); - when(mockBeanFactory.isTypeMatch(eq("TestPool"), eq(Pool.class))).thenReturn(false); - + factoryBean.setAttributes(mockRegionAttributes); factoryBean.setBeanFactory(mockBeanFactory); factoryBean.setPersistent(true); - factoryBean.setPoolName("TestPool"); Region actualRegion = factoryBean.createRegion(mockClientCache, "TestRegion"); - assertSame(mockRegion, actualRegion); + assertThat(actualRegion).isEqualTo(mockRegion); + verify(mockBeanFactory, times(1)).getBean(eq("TestPool"), eq(Pool.class)); 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, times(1)).containsBean(eq("TestPool")); - verify(mockBeanFactory, never()).getBean(eq("TestPool")); + verify(mockRegionAttributes, times(1)).getPoolName(); verify(mockRegion, never()).loadSnapshot(any(InputStream.class)); } @@ -235,7 +225,7 @@ public class ClientRegionFactoryBeanTest { Region actualRegion = factoryBean.createRegion(mockClientCache, "TestRegion"); - assertSame(mockRegion, actualRegion); + assertThat(actualRegion).isEqualTo(mockRegion); verifyZeroInteractions(mockBeanFactory); verify(mockClientCache, times(1)) @@ -245,7 +235,7 @@ public class ClientRegionFactoryBeanTest { @Test @SuppressWarnings("unchecked") - public void createRegionWithSubRegionCreation() throws Exception { + public void createRegionAsSubRegion() throws Exception { BeanFactory mockBeanFactory = mock(BeanFactory.class); @@ -266,7 +256,7 @@ public class ClientRegionFactoryBeanTest { Region actualRegion = factoryBean.createRegion(mockClientCache, "TestSubRegion"); - assertSame(mockSubRegion, actualRegion); + assertThat(actualRegion).isEqualTo(mockSubRegion); verifyZeroInteractions(mockBeanFactory); verify(mockClientCache, times(1)) @@ -277,108 +267,142 @@ public class ClientRegionFactoryBeanTest { @Test @SuppressWarnings("unchecked") - public void configurePoolFromRegionAttributesAndEagerlyInitializesPool() { + public void createClientRegionFactoryFromClientCache() { + + ClientCache mockClientCache = mock(ClientCache.class); + + ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); + + when(mockClientCache.createClientRegionFactory(any(ClientRegionShortcut.class))) + .thenReturn(mockClientRegionFactory); + + assertThat(factoryBean.createClientRegionFactory(mockClientCache, ClientRegionShortcut.CACHING_PROXY)) + .isEqualTo(mockClientRegionFactory); + + verify(mockClientCache, times(1)) + .createClientRegionFactory(eq(ClientRegionShortcut.CACHING_PROXY)); + } + + @Test + @SuppressWarnings("unchecked") + public void configurePoolFromClientRegionFactoryBeanAndEagerlyInitializePool() { BeanFactory mockBeanFactory = mock(BeanFactory.class); ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); + Pool mockPool = mock(Pool.class); + + when(mockBeanFactory.getBean(eq("MockPool"), eq(Pool.class))).thenReturn(mockPool); + + factoryBean.setBeanFactory(mockBeanFactory); + factoryBean.setPoolName("MockPool"); + factoryBean.configure(mockClientRegionFactory); + + verify(mockBeanFactory, times(1)).getBean(eq("MockPool"), eq(Pool.class)); + verify(mockClientRegionFactory, times(1)).setPoolName(eq("MockPool")); + } + + @Test + @SuppressWarnings("unchecked") + public void configurePoolFromClientRegionFactoryBeanEvenWhenRegionAttributesPoolNameIsSet() { + + BeanFactory mockBeanFactory = mock(BeanFactory.class); + + ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); + + Pool mockPool = mock(Pool.class); + RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); - when(mockBeanFactory.containsBean(eq("TestPool"))).thenReturn(true); - when(mockBeanFactory.isTypeMatch(eq("TestPool"), eq(Pool.class))).thenReturn(true); + when(mockBeanFactory.getBean(anyString(), eq(Pool.class))).thenReturn(mockPool); + when(mockRegionAttributes.getPoolName()).thenReturn("TestPool"); + + factoryBean.setAttributes(mockRegionAttributes); + factoryBean.setBeanFactory(mockBeanFactory); + factoryBean.setPoolName("MockPool"); + factoryBean.configure(mockClientRegionFactory); + + verify(mockBeanFactory, times(1)).getBean(eq("MockPool"), eq(Pool.class)); + verify(mockBeanFactory, never()).getBean(eq("TestPool"), eq(Pool.class)); + verify(mockClientRegionFactory, times(1)).setPoolName(eq("MockPool")); + verify(mockRegionAttributes, times(1)).getPoolName(); + } + + @Test + @SuppressWarnings("unchecked") + public void configurePoolFromRegionAttributesAndEagerlyInitializePool() { + + BeanFactory mockBeanFactory = mock(BeanFactory.class); + + ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); + + Pool mockPool = mock(Pool.class); + + RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); + + when(mockBeanFactory.getBean(eq("TestPool"), eq(Pool.class))).thenReturn(mockPool); when(mockRegionAttributes.getPoolName()).thenReturn("TestPool"); factoryBean.setAttributes(mockRegionAttributes); factoryBean.setBeanFactory(mockBeanFactory); factoryBean.configure(mockClientRegionFactory); - verify(mockBeanFactory, times(1)).containsBean(eq("TestPool")); - verify(mockBeanFactory, times(1)).isTypeMatch(eq("TestPool"), eq(Pool.class)); verify(mockBeanFactory, times(1)).getBean(eq("TestPool"), eq(Pool.class)); verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPool")); verify(mockRegionAttributes, times(1)).getPoolName(); } - @Test + @Test(expected = IllegalArgumentException.class) @SuppressWarnings("unchecked") - public void configurePoolFromRegionAttributesThrowsExceptionWhileEagerlyInitializingPool() { + public void configurePoolThrowsExceptionWhileEagerlyInitializingPool() { BeanFactory mockBeanFactory = mock(BeanFactory.class); ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); - RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); + when(mockBeanFactory.getBean(anyString(), eq(Pool.class))).thenThrow(new BeanCreationException("test")); - when(mockBeanFactory.containsBean(eq("TestPool"))).thenReturn(true); - when(mockBeanFactory.isTypeMatch(eq("TestPool"), eq(Pool.class))).thenReturn(true); - when(mockBeanFactory.getBean(eq("TestPool"), eq(Pool.class))) - .thenThrow(new BeanCreationException("TEST")); - when(mockRegionAttributes.getPoolName()).thenReturn("TestPool"); - - factoryBean.setAttributes(mockRegionAttributes); factoryBean.setBeanFactory(mockBeanFactory); - factoryBean.configure(mockClientRegionFactory); + factoryBean.setPoolName("MockPool"); - verify(mockBeanFactory, times(1)).containsBean(eq("TestPool")); - verify(mockBeanFactory, times(1)).isTypeMatch(eq("TestPool"), eq(Pool.class)); - verify(mockBeanFactory, times(1)).getBean(eq("TestPool"), eq(Pool.class)); - verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPool")); - verify(mockRegionAttributes, times(1)).getPoolName(); + try { + factoryBean.configure(mockClientRegionFactory); + } + catch (IllegalArgumentException expected) { + + assertThat(expected).hasMessage("[MockPool] is not resolvable as a Pool in the application context"); + assertThat(expected).hasNoCause(); + + throw expected; + } + finally { + verify(mockBeanFactory, times(1)).getBean(eq("MockPool"), eq(Pool.class)); + verify(mockClientRegionFactory, never()).setPoolName(eq("MockPool")); + } } @Test @SuppressWarnings("unchecked") - public void configurePoolFromRegionAttributesDoesNotEagerlyInitializePoolWhenNotPoolTypeMatch() { + public void doesNotConfigurePoolWhenClientRegionFactoryBeanPoolIsDefaultPool() { BeanFactory mockBeanFactory = mock(BeanFactory.class); ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); - RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); - - when(mockBeanFactory.containsBean(eq("TestPool"))).thenReturn(true); - when(mockBeanFactory.isTypeMatch(eq("TestPool"), eq(Pool.class))).thenReturn(false); - when(mockRegionAttributes.getPoolName()).thenReturn("TestPool"); - - factoryBean.setAttributes(mockRegionAttributes); factoryBean.setBeanFactory(mockBeanFactory); + factoryBean.setPoolName(ClientRegionFactoryBean.DEFAULT_POOL_NAME); factoryBean.configure(mockClientRegionFactory); - verify(mockBeanFactory, times(1)).containsBean(eq("TestPool")); - verify(mockBeanFactory, times(1)).isTypeMatch(eq("TestPool"), eq(Pool.class)); - verify(mockBeanFactory, never()).getBean(anyString(), eq(Pool.class)); - verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPool")); - verify(mockRegionAttributes, times(1)).getPoolName(); - } + assertThat(factoryBean.getPoolName().orElse(null)).isEqualTo(ClientRegionFactoryBean.DEFAULT_POOL_NAME); - @Test - @SuppressWarnings("unchecked") - public void doesNotConfigurePoolFromRegionAttributesWhenPoolIsUnresolvable() { - - BeanFactory mockBeanFactory = mock(BeanFactory.class); - - ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); - - RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); - - when(mockBeanFactory.containsBean(anyString())).thenReturn(false); - when(mockRegionAttributes.getPoolName()).thenReturn("TestPool"); - - factoryBean.setAttributes(mockRegionAttributes); - factoryBean.setBeanFactory(mockBeanFactory); - factoryBean.configure(mockClientRegionFactory); - - verify(mockBeanFactory, times(1)).containsBean(eq("TestPool")); - verify(mockBeanFactory, never()).isTypeMatch(anyString(), eq(Pool.class)); verify(mockBeanFactory, never()).getBean(anyString(), eq(Pool.class)); verify(mockClientRegionFactory, never()).setPoolName(anyString()); - verify(mockRegionAttributes, times(1)).getPoolName(); } @Test @SuppressWarnings("unchecked") - public void doesNotConfigurePoolFromRegionAttributesWhenPoolIsDefaultPool() { + public void doesNotConfigurePoolWhenRegionAttributesPoolIsDefaultPool() { BeanFactory mockBeanFactory = mock(BeanFactory.class); @@ -392,9 +416,8 @@ public class ClientRegionFactoryBeanTest { factoryBean.setBeanFactory(mockBeanFactory); factoryBean.configure(mockClientRegionFactory); - verify(factoryBean, never()).isPoolResolvable(anyString()); - verify(mockBeanFactory, never()).containsBean(anyString()); - verify(mockBeanFactory, never()).isTypeMatch(anyString(), eq(Pool.class)); + assertThat(factoryBean.getPoolName().orElse(null)).isNull(); + verify(mockBeanFactory, never()).getBean(anyString(), eq(Pool.class)); verify(mockClientRegionFactory, never()).setPoolName(anyString()); verify(mockRegionAttributes, times(1)).getPoolName(); @@ -402,7 +425,7 @@ public class ClientRegionFactoryBeanTest { @Test @SuppressWarnings("unchecked") - public void doesNotConfigurePoolFromRegionAttributesWhenPoolIsEmpty() { + public void doesNotConfigurePoolWhenDeclaredPoolIsEmpty() { BeanFactory mockBeanFactory = mock(BeanFactory.class); @@ -414,12 +437,11 @@ public class ClientRegionFactoryBeanTest { factoryBean.setAttributes(mockRegionAttributes); factoryBean.setBeanFactory(mockBeanFactory); + factoryBean.setPoolName(""); factoryBean.configure(mockClientRegionFactory); - verify(factoryBean, never()).isNotDefaultPool(anyString()); - verify(factoryBean, never()).isPoolResolvable(anyString()); - verify(mockBeanFactory, never()).containsBean(anyString()); - verify(mockBeanFactory, never()).isTypeMatch(anyString(), eq(Pool.class)); + assertThat(factoryBean.getPoolName().orElse(null)).isEqualTo(""); + verify(mockBeanFactory, never()).getBean(anyString(), eq(Pool.class)); verify(mockClientRegionFactory, never()).setPoolName(anyString()); verify(mockRegionAttributes, times(1)).getPoolName(); @@ -427,7 +449,7 @@ public class ClientRegionFactoryBeanTest { @Test @SuppressWarnings("unchecked") - public void doesNotConfigurePoolFromRegionAttributesWhenPoolIsNull() { + public void doesNotConfigurePoolWhenDeclaredPoolIsNull() { BeanFactory mockBeanFactory = mock(BeanFactory.class); @@ -438,190 +460,15 @@ public class ClientRegionFactoryBeanTest { when(mockRegionAttributes.getPoolName()).thenReturn(null); factoryBean.setAttributes(mockRegionAttributes); - factoryBean.setBeanFactory(mockBeanFactory); - factoryBean.configure(mockClientRegionFactory); - - verify(factoryBean, never()).isNotDefaultPool(anyString()); - verify(factoryBean, never()).isPoolResolvable(anyString()); - verify(mockBeanFactory, never()).containsBean(anyString()); - verify(mockBeanFactory, never()).isTypeMatch(anyString(), eq(Pool.class)); - verify(mockBeanFactory, never()).getBean(anyString(), eq(Pool.class)); - verify(mockClientRegionFactory, never()).setPoolName(anyString()); - verify(mockRegionAttributes, times(1)).getPoolName(); - } - - @Test - @SuppressWarnings("unchecked") - public void configurePoolFromClientRegionFactoryBeanAndEagerlyInitializesPool() { - - BeanFactory mockBeanFactory = mock(BeanFactory.class); - - ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); - - when(mockBeanFactory.containsBean(eq("MockPool"))).thenReturn(true); - when(mockBeanFactory.isTypeMatch(eq("MockPool"), eq(Pool.class))).thenReturn(true); - - factoryBean.setBeanFactory(mockBeanFactory); - factoryBean.setPoolName("MockPool"); - factoryBean.configure(mockClientRegionFactory); - - verify(mockBeanFactory, times(1)).containsBean(eq("MockPool")); - verify(mockBeanFactory, times(1)).isTypeMatch(eq("MockPool"), eq(Pool.class)); - verify(mockBeanFactory, times(1)).getBean(eq("MockPool"), eq(Pool.class)); - verify(mockClientRegionFactory, times(1)).setPoolName(eq("MockPool")); - } - - @Test - @SuppressWarnings("unchecked") - public void configurePoolFromClientRegionFactoryBeanThrowsExceptionWhileEagerlyInitializingPool() { - - BeanFactory mockBeanFactory = mock(BeanFactory.class); - - ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); - - when(mockBeanFactory.containsBean(eq("MockPool"))).thenReturn(true); - when(mockBeanFactory.isTypeMatch(eq("MockPool"), eq(Pool.class))).thenReturn(true); - when(mockBeanFactory.getBean(eq("MockPool"), eq(Pool.class))).thenThrow(new BeanCreationException("TEST")); - - factoryBean.setBeanFactory(mockBeanFactory); - factoryBean.setPoolName("MockPool"); - factoryBean.configure(mockClientRegionFactory); - - verify(mockBeanFactory, times(1)).containsBean(eq("MockPool")); - verify(mockBeanFactory, times(1)).isTypeMatch(eq("MockPool"), eq(Pool.class)); - verify(mockBeanFactory, times(1)).getBean(eq("MockPool"), eq(Pool.class)); - verify(mockClientRegionFactory, times(1)).setPoolName(eq("MockPool")); - } - - @Test - @SuppressWarnings("unchecked") - public void configurePoolFromClientRegionFactoryBeanDoesNotEagerlyInitializePoolWhenNotPoolTypeMatch() { - - BeanFactory mockBeanFactory = mock(BeanFactory.class); - - ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); - - when(mockBeanFactory.containsBean(eq("MockPool"))).thenReturn(true); - when(mockBeanFactory.isTypeMatch(anyString(), eq(Pool.class))).thenReturn(false); - - factoryBean.setBeanFactory(mockBeanFactory); - factoryBean.setPoolName("MockPool"); - factoryBean.configure(mockClientRegionFactory); - - verify(mockBeanFactory, times(1)).containsBean(eq("MockPool")); - verify(mockBeanFactory, times(1)).isTypeMatch(eq("MockPool"), eq(Pool.class)); - verify(mockBeanFactory, never()).getBean(anyString(), eq(Pool.class)); - verify(mockClientRegionFactory, times(1)).setPoolName(eq("MockPool")); - } - - @Test - @SuppressWarnings("unchecked") - public void configuresPoolFromClientRegionFactoryBeanEvenWhenRegionAttributesPoolNameIsSet() { - - BeanFactory mockBeanFactory = mock(BeanFactory.class); - - ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); - - RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); - - when(mockBeanFactory.containsBean(anyString())).thenReturn(true); - when(mockBeanFactory.isTypeMatch(anyString(), eq(Pool.class))).thenReturn(true); - when(mockRegionAttributes.getPoolName()).thenReturn("TestPool"); - - factoryBean.setAttributes(mockRegionAttributes); - factoryBean.setBeanFactory(mockBeanFactory); - factoryBean.setPoolName("MockPool"); - factoryBean.configure(mockClientRegionFactory); - - InOrder inOrderVerifier = inOrder(mockBeanFactory, mockClientRegionFactory); - - inOrderVerifier.verify(mockBeanFactory, times(1)).containsBean(eq("TestPool")); - inOrderVerifier.verify(mockBeanFactory, times(1)).isTypeMatch(eq("TestPool"), eq(Pool.class)); - inOrderVerifier.verify(mockBeanFactory, times(1)).getBean(eq("TestPool"), eq(Pool.class)); - inOrderVerifier.verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPool")); - inOrderVerifier.verify(mockBeanFactory, times(1)).containsBean(eq("MockPool")); - inOrderVerifier.verify(mockBeanFactory, times(1)).isTypeMatch(eq("MockPool"), eq(Pool.class)); - inOrderVerifier.verify(mockBeanFactory, times(1)).getBean(eq("MockPool"), eq(Pool.class)); - inOrderVerifier.verify(mockClientRegionFactory, times(1)).setPoolName(eq("MockPool")); - } - - @Test - @SuppressWarnings("unchecked") - public void doesNotConfigurePoolFromClientRegionFactoryBeanWhenPoolIsUnresolvable() { - - BeanFactory mockBeanFactory = mock(BeanFactory.class); - - ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); - - when(mockBeanFactory.containsBean(anyString())).thenReturn(false); - - factoryBean.setBeanFactory(mockBeanFactory); - factoryBean.setPoolName("MockPool"); - factoryBean.configure(mockClientRegionFactory); - - verify(mockBeanFactory, times(1)).containsBean(eq("MockPool")); - verify(mockBeanFactory, never()).isTypeMatch(anyString(), eq(Pool.class)); - verify(mockBeanFactory, never()).getBean(anyString(), eq(Pool.class)); - verify(mockClientRegionFactory, never()).setPoolName(anyString()); - } - - @Test - @SuppressWarnings("unchecked") - public void doesNotConfigurePoolFromClientRegionFactoryBeanWhenPoolIsDefaultPool() { - - BeanFactory mockBeanFactory = mock(BeanFactory.class); - - ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); - - factoryBean.setBeanFactory(mockBeanFactory); - factoryBean.setPoolName(ClientRegionFactoryBean.DEFAULT_POOL_NAME); - factoryBean.configure(mockClientRegionFactory); - - verify(factoryBean, never()).isPoolResolvable(anyString()); - verify(mockBeanFactory, never()).containsBean(anyString()); - verify(mockBeanFactory, never()).isTypeMatch(anyString(), eq(Pool.class)); - verify(mockBeanFactory, never()).getBean(anyString(), eq(Pool.class)); - verify(mockClientRegionFactory, never()).setPoolName(anyString()); - } - - @Test - @SuppressWarnings("unchecked") - public void doesNotConfigurePoolFromClientRegionFactoryBeanWhenPoolIsEmpty() { - - BeanFactory mockBeanFactory = mock(BeanFactory.class); - - ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); - - factoryBean.setBeanFactory(mockBeanFactory); - factoryBean.setPoolName(""); - factoryBean.configure(mockClientRegionFactory); - - verify(factoryBean, never()).isNotDefaultPool(anyString()); - verify(factoryBean, never()).isPoolResolvable(anyString()); - verify(mockBeanFactory, never()).containsBean(anyString()); - verify(mockBeanFactory, never()).isTypeMatch(anyString(), eq(Pool.class)); - verify(mockBeanFactory, never()).getBean(anyString(), eq(Pool.class)); - verify(mockClientRegionFactory, never()).setPoolName(anyString()); - } - - @Test - @SuppressWarnings("unchecked") - public void doesNotConfigurePoolFromClientRegionFactoryBeanWhenPoolIsNull() { - - BeanFactory mockBeanFactory = mock(BeanFactory.class); - - ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); - factoryBean.setBeanFactory(mockBeanFactory); factoryBean.setPoolName(null); factoryBean.configure(mockClientRegionFactory); - verify(factoryBean, never()).isNotDefaultPool(anyString()); - verify(factoryBean, never()).isPoolResolvable(anyString()); - verify(mockBeanFactory, never()).containsBean(anyString()); - verify(mockBeanFactory, never()).isTypeMatch(anyString(), eq(Pool.class)); + assertThat(factoryBean.getPoolName().orElse(null)).isNull(); + verify(mockBeanFactory, never()).getBean(anyString(), eq(Pool.class)); verify(mockClientRegionFactory, never()).setPoolName(anyString()); + verify(mockRegionAttributes, times(1)).getPoolName(); } @Test @@ -666,22 +513,6 @@ public class ClientRegionFactoryBeanTest { assertTrue(factoryBean.isPersistent()); } - @Test - public void isPersistentUnspecifiedIsCorrect() { - - assertTrue(factoryBean.isPersistentUnspecified()); - - factoryBean.setPersistent(true); - - assertTrue(factoryBean.isPersistent()); - assertFalse(factoryBean.isPersistentUnspecified()); - - factoryBean.setPersistent(false); - - assertTrue(factoryBean.isNotPersistent()); - assertFalse(factoryBean.isPersistentUnspecified()); - } - @Test public void isNotPersistentIsCorrect() { diff --git a/src/test/java/org/springframework/data/gemfire/client/DurableClientCacheIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/client/DurableClientCacheIntegrationTest.java index 1982c4a1..bb9346ba 100644 --- a/src/test/java/org/springframework/data/gemfire/client/DurableClientCacheIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/DurableClientCacheIntegrationTest.java @@ -60,7 +60,7 @@ import org.springframework.data.gemfire.test.support.ThreadUtils; import org.springframework.data.gemfire.util.DistributedSystemUtils; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.Assert; import org.springframework.util.SocketUtils; @@ -82,7 +82,7 @@ import org.springframework.util.SocketUtils; * @see org.apache.geode.cache.util.CacheListenerAdapter * @since 1.6.3 */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration @SuppressWarnings("all") public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServerIntegrationTest { @@ -117,30 +117,30 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ private Region example; @BeforeClass - public static void setupGemFireServer() throws IOException { + public static void startGemFireServer() throws IOException { serverPort = setSystemProperty(CACHE_SERVER_PORT_SYSTEM_PROPERTY, SocketUtils.findAvailableTcpPort()); serverProcess = startGemFireServer(DurableClientCacheIntegrationTest.class); } @AfterClass - public static void tearDownGemFireServer() { - serverProcess = stopGemFireServer(serverProcess); + public static void stopGemFireServer() { + stopGemFireServer(serverProcess); clearSystemProperties(DurableClientCacheIntegrationTest.class); } - protected static boolean isAfterDirtiesContext() { + private static boolean isAfterDirtiesContext() { return DIRTIES_CONTEXT.get(); } - protected static boolean isBeforeDirtiesContext() { + private static boolean isBeforeDirtiesContext() { return !isAfterDirtiesContext(); } - protected boolean dirtiesContext() { + private boolean dirtiesContext() { return !DIRTIES_CONTEXT.getAndSet(true); } - protected T valueBeforeAndAfterDirtiesContext(T before, T after) { + private T valueBeforeAndAfterDirtiesContext(T before, T after) { return (isBeforeDirtiesContext() ? before : after); } @@ -161,6 +161,7 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ @After public void tearDown() { + if (dirtiesContext()) { closeApplicationContext(); runClientCacheProducer(); @@ -171,6 +172,7 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ } protected void closeApplicationContext() { + applicationContext.close(); assertThat(applicationContext.isRunning(), is(false)); @@ -178,6 +180,7 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ } protected void runClientCacheProducer() { + try { ClientCache gemfireClientCache = new ClientCacheFactory() .addPoolServer(SERVER_HOST, serverPort) @@ -197,17 +200,17 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ } } - protected void setSystemProperties() { + private void setSystemProperties() { System.setProperty(CLIENT_CACHE_INTERESTS_RESULT_POLICY_SYSTEM_PROPERTY, InterestResultPolicyType.NONE.name()); System.setProperty(DURABLE_CLIENT_TIMEOUT_SYSTEM_PROPERTY, "600"); } - protected void assertRegion(Region region, String expectedName, DataPolicy expectedDataPolicy) { + private void assertRegion(Region region, String expectedName, DataPolicy expectedDataPolicy) { assertRegion(region, expectedName, String.format("%1$s%2$s", Region.SEPARATOR, expectedName), expectedDataPolicy); } - protected void assertRegion(Region region, String expectedName, String expectedPath, + private void assertRegion(Region region, String expectedName, String expectedPath, DataPolicy expectedDataPolicy) { assertThat(region, is(notNullValue())); @@ -217,7 +220,8 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ assertThat(region.getAttributes().getDataPolicy(), is(equalTo(expectedDataPolicy))); } - protected void assertRegionValues(Region region, Object... values) { + private void assertRegionValues(Region region, Object... values) { + assertThat(region.size(), is(equalTo(values.length))); for (Object value : values) { @@ -225,7 +229,7 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ } } - protected void waitForRegionEntryEvents() { + private void waitForRegionEntryEvents() { ThreadUtils.timedWait(TimeUnit.SECONDS.toMillis(5), TimeUnit.MILLISECONDS.toMillis(500), new ThreadUtils.WaitCondition() { @Override public boolean waiting() { @@ -238,6 +242,7 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ @Test @DirtiesContext public void durableClientGetsInitializedWithDataOnServer() { + assumeTrue(isBeforeDirtiesContext()); assertRegionValues(example, 1, 2, 3); assertThat(regionCacheListenerEventValues.isEmpty(), is(true)); @@ -245,6 +250,7 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ @Test public void durableClientGetsUpdatesFromServerWhileClientWasOffline() { + assumeTrue(isAfterDirtiesContext()); assertThat(example.isEmpty(), is(true)); @@ -264,7 +270,9 @@ public class DurableClientCacheIntegrationTest extends AbstractGemFireClientServ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof Pool && "gemfireServerPool".equals(beanName)) { + Pool gemfireServerPool = (Pool) bean; if (isBeforeDirtiesContext()) { diff --git a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest.java index 39bfd733..d667a0b0 100644 --- a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest.java @@ -16,18 +16,12 @@ package org.springframework.data.gemfire.client; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.CoreMatchers.sameInstance; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.TimeUnit; import javax.annotation.Resource; @@ -39,14 +33,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import org.springframework.data.gemfire.GemfireUtils; import org.springframework.data.gemfire.fork.ServerProcess; -import org.springframework.data.gemfire.process.ProcessExecutor; import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; import org.springframework.data.gemfire.test.support.FileSystemUtils; -import org.springframework.data.gemfire.test.support.ThreadUtils; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.util.Assert; +import org.springframework.test.context.junit4.SpringRunner; /** * The GemFireDataSourceIntegrationTest class is a test suite of test cases testing the contract and functionality @@ -64,12 +57,57 @@ import org.springframework.util.Assert; * @see org.apache.geode.cache.client.ClientCache * @since 1.7.0 */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration @SuppressWarnings({ "rawtypes", "unused"}) -public class GemFireDataSourceIntegrationTest { +public class GemFireDataSourceIntegrationTest extends ClientServerIntegrationTestsSupport { - private static ProcessWrapper serverProcess; + private static final String GEMFIRE_LOG_LEVEL = "error"; + + private static ProcessWrapper gemfireServer; + + @BeforeClass + public static void startGemFireServer() throws IOException { + + int availablePort = findAvailablePort(); + + String serverName = GemFireDataSourceIntegrationTest.class.getSimpleName().concat("Server"); + + File serverWorkingDirectory = new File(FileSystemUtils.WORKING_DIRECTORY, serverName.toLowerCase()); + + List arguments = new ArrayList<>(); + + arguments.add(String.format("-Dgemfire.name=%s", serverName)); + arguments.add(String.format("-Dgemfire.log-level=%s", GEMFIRE_LOG_LEVEL)); + arguments.add(String.format("-Dspring.data.gemfire.cache.server.port=%d", availablePort)); + arguments.add(GemFireDataSourceIntegrationTest.class.getName() + .replace(".", "/").concat("-server-context.xml")); + + gemfireServer = run(serverWorkingDirectory, ServerProcess.class, + arguments.toArray(new String[arguments.size()])); + + waitForServerToStart(DEFAULT_HOSTNAME, availablePort); + + configureGemFireClient(availablePort); + } + + private static void configureGemFireClient(int availablePort) { + System.setProperty("gemfire.log-level", "error"); + System.setProperty("spring.data.gemfire.cache.server.port", String.valueOf(availablePort)); + } + + @AfterClass + public static void stopGemFireServer() { + + stop(gemfireServer); + + System.clearProperty("gemfire.log-level"); + System.clearProperty("spring.data.gemfire.cache.server.port"); + + if (Boolean.valueOf(System.getProperty("spring.gemfire.fork.clean", Boolean.TRUE.toString()))) { + org.springframework.util.FileSystemUtils.deleteRecursively(gemfireServer.getWorkingDirectory()); + } + } @Autowired private ApplicationContext applicationContext; @@ -86,64 +124,23 @@ public class GemFireDataSourceIntegrationTest { @Resource(name = "ServerOnlyRegion") private Region serverOnlyRegion; - @BeforeClass - public static void setupBeforeClass() throws IOException { - System.setProperty("gemfire.log-level", "warning"); + @SuppressWarnings("unchecked") + private void assertRegion(Region actualRegion, String expectedRegionName) { - String serverName = "GemFireDataSourceSpringBasedServer"; - - File serverWorkingDirectory = new File(FileSystemUtils.WORKING_DIRECTORY, serverName.toLowerCase()); - - Assert.isTrue(serverWorkingDirectory.isDirectory() || serverWorkingDirectory.mkdirs()); - - List arguments = new ArrayList(); - - arguments.add(String.format("-Dgemfire.name=%1$s", serverName)); - arguments.add(GemFireDataSourceIntegrationTest.class.getName().replace(".", "/").concat("-server-context.xml")); - - serverProcess = ProcessExecutor.launch(serverWorkingDirectory, ServerProcess.class, - arguments.toArray(new String[arguments.size()])); - - waitForProcessStart(TimeUnit.SECONDS.toMillis(20), serverProcess, ServerProcess.getServerProcessControlFilename()); - - System.out.println("Spring configured/bootstrapped GemFire Cache Server Process for ClientCache DataSource Test should be running..."); - } - - private static void waitForProcessStart(final long milliseconds, final ProcessWrapper process, final String processControlFilename) { - ThreadUtils.timedWait(milliseconds, TimeUnit.MILLISECONDS.toMillis(500), new ThreadUtils.WaitCondition() { - private File processControlFile = new File(process.getWorkingDirectory(), processControlFilename); - - @Override public boolean waiting() { - return !processControlFile.isFile(); - } - }); - } - - @AfterClass - public static void tearDown() { - serverProcess.shutdown(); - - if (Boolean.valueOf(System.getProperty("spring.gemfire.fork.clean", Boolean.TRUE.toString()))) { - org.springframework.util.FileSystemUtils.deleteRecursively(serverProcess.getWorkingDirectory()); - } - } - - protected void assertRegion(Region actualRegion, String expectedRegionName) { - assertThat(actualRegion, is(not(nullValue()))); - assertThat(actualRegion.getName(), is(equalTo(expectedRegionName))); - assertThat(actualRegion.getFullPath(), is(equalTo(String.format("%1$s%2$s", - Region.SEPARATOR, expectedRegionName)))); - assertThat(gemfireClientCache.getRegion(actualRegion.getFullPath()), is(sameInstance(actualRegion))); - assertThat(applicationContext.containsBean(expectedRegionName), is(true)); - assertThat(applicationContext.getBean(expectedRegionName, Region.class), is(sameInstance(actualRegion))); + assertThat(actualRegion).isNotNull(); + assertThat(actualRegion.getName()).isEqualTo(expectedRegionName); + assertThat(actualRegion.getFullPath()).isEqualTo(GemfireUtils.toRegionPath(expectedRegionName)); + assertThat(gemfireClientCache.getRegion(actualRegion.getFullPath())).isSameAs(actualRegion); + assertThat(applicationContext.containsBean(expectedRegionName)).isTrue(); + assertThat(applicationContext.getBean(expectedRegionName, Region.class)).isSameAs(actualRegion); } @Test @SuppressWarnings("unchecked") public void clientProxyRegionBeansExist() { + assertRegion(clientOnlyRegion, "ClientOnlyRegion"); assertRegion(clientServerRegion, "ClientServerRegion"); assertRegion(serverOnlyRegion, "ServerOnlyRegion"); } - } diff --git a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests.java index 29b65383..088477b6 100644 --- a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import org.springframework.data.gemfire.GemfireUtils; import org.springframework.data.gemfire.fork.ServerProcess; import org.springframework.data.gemfire.process.ProcessWrapper; import org.springframework.data.gemfire.repository.sample.Person; @@ -44,6 +45,7 @@ import org.springframework.test.context.junit4.SpringRunner; */ @RunWith(SpringRunner.class) @ContextConfiguration +// TODO: merge with o.s.d.g.client.GemfireDataSoruceIntegrationTest public class GemFireDataSourceIntegrationTests extends ClientServerIntegrationTestsSupport { private static ProcessWrapper gemfireServer; @@ -53,6 +55,7 @@ public class GemFireDataSourceIntegrationTests extends ClientServerIntegrationTe @BeforeClass public static void startGemFireServer() throws Exception { + int availablePort = findAvailablePort(); gemfireServer = run(ServerProcess.class, @@ -70,11 +73,12 @@ public class GemFireDataSourceIntegrationTests extends ClientServerIntegrationTe stop(gemfireServer); } - protected void assertRegion(Region region, String name, DataPolicy dataPolicy) { - assertRegion(region, name, String.format("%1$s%2$s", Region.SEPARATOR, "simple"), dataPolicy); + private void assertRegion(Region region, String name, DataPolicy dataPolicy) { + assertRegion(region, name, GemfireUtils.toRegionPath("simple"), dataPolicy); } - protected void assertRegion(Region region, String name, String fullPath, DataPolicy dataPolicy) { + private void assertRegion(Region region, String name, String fullPath, DataPolicy dataPolicy) { + assertThat(region).isNotNull(); assertThat(region.getName()).isEqualTo(name); assertThat(region.getFullPath()).isEqualTo(fullPath); @@ -84,33 +88,36 @@ public class GemFireDataSourceIntegrationTests extends ClientServerIntegrationTe @Test public void gemfireServerDataSourceCreated() { - Pool pool = applicationContext.getBean("gemfirePool", Pool.class); + + Pool pool = this.applicationContext.getBean("gemfirePool", Pool.class); assertThat(pool).isNotNull(); assertThat(pool.getSubscriptionEnabled()).isTrue(); - List regionList = Arrays.asList(applicationContext.getBeanNamesForType(Region.class)); + List regionList = Arrays.asList(this.applicationContext.getBeanNamesForType(Region.class)); assertThat(regionList).hasSize(3); assertThat(regionList.contains("r1")).isTrue(); assertThat(regionList.contains("r2")).isTrue(); assertThat(regionList.contains("simple")).isTrue(); - Region simple = applicationContext.getBean("simple", Region.class); + Region simple = this.applicationContext.getBean("simple", Region.class); assertRegion(simple, "simple", DataPolicy.EMPTY); } @Test public void repositoryCreatedAndFunctional() { + Person daveMathews = new Person(1L, "Dave", "Mathews"); - PersonRepository repository = applicationContext.getBean(PersonRepository.class); + + PersonRepository repository = this.applicationContext.getBean(PersonRepository.class); assertThat(repository.save(daveMathews)).isSameAs(daveMathews); Optional result = repository.findById(1L); assertThat(result.isPresent()).isTrue(); - assertThat(result.get().getFirstname()).isEqualTo("Dave"); + assertThat(result.map(Person::getFirstname).orElse(null)).isEqualTo("Dave"); } } diff --git a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTest.java index dc9663e0..2212938f 100644 --- a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTest.java @@ -16,13 +16,6 @@ package org.springframework.data.gemfire.client; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.CoreMatchers.sameInstance; -import static org.junit.Assert.assertThat; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -35,6 +28,7 @@ import javax.annotation.Resource; import org.apache.geode.cache.Region; import org.apache.geode.cache.client.ClientCache; import org.apache.geode.distributed.ServerLauncher; +import org.assertj.core.api.Assertions; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -42,6 +36,7 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.core.io.ClassPathResource; +import org.springframework.data.gemfire.GemfireUtils; import org.springframework.data.gemfire.fork.GemFireBasedServerProcess; import org.springframework.data.gemfire.process.ProcessExecutor; import org.springframework.data.gemfire.process.ProcessWrapper; @@ -67,9 +62,12 @@ import org.springframework.util.StringUtils; @RunWith(SpringRunner.class) @ContextConfiguration @SuppressWarnings({ "rawtypes", "unused"}) +// TODO: slow test! public class GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTest { - private static ProcessWrapper serverProcess; + private static final String GEMFIRE_LOG_LEVEL = "error"; + + private static ProcessWrapper gemfireServer; @Autowired private ApplicationContext applicationContext; @@ -87,9 +85,9 @@ public class GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTe private Region anotherServerRegion; @BeforeClass - public static void setupBeforeClass() throws IOException { + public static void startGemFireServer() throws IOException { - System.setProperty("gemfire.log-level", "error"); + System.setProperty("gemfire.log-level", GEMFIRE_LOG_LEVEL); String serverName = "GemFireDataSourceGemFireBasedServer"; @@ -102,20 +100,16 @@ public class GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTe Assert.isTrue(new File(serverWorkingDirectory, "cache.xml").isFile(), String.format( "Expected a cache.xml file to exist in directory (%1$s)!", serverWorkingDirectory)); - List arguments = new ArrayList(5); + List arguments = new ArrayList<>(5); arguments.add(ServerLauncher.Command.START.getName()); arguments.add(String.format("-Dgemfire.name=%1$s", serverName)); - arguments.add(String.format("-Dgemfire.mcast-port=%1$s", "0")); - arguments.add(String.format("-Dgemfire.log-level=%1$s", "warning")); - //arguments.add(String.format("-Dgemfire.cache-xml-file=%1$s", "gemfire-datasource-integration-test-cache.xml")); + arguments.add(String.format("-Dgemfire.log-level=%1$s", "error")); - serverProcess = ProcessExecutor.launch(serverWorkingDirectory, customClasspath(), ServerLauncher.class, + gemfireServer = ProcessExecutor.launch(serverWorkingDirectory, customClasspath(), ServerLauncher.class, arguments.toArray(new String[arguments.size()])); - waitForProcessStart(TimeUnit.SECONDS.toMillis(20), serverProcess, GemFireBasedServerProcess.getServerProcessControlFilename()); - - System.out.println("GemFire-based Cache Server Process for ClientCache DataSource Test should be running and connected..."); + waitForProcessStart(TimeUnit.SECONDS.toMillis(20), gemfireServer, GemFireBasedServerProcess.getServerProcessControlFilename()); } private static void writeAsCacheXmlFileToDirectory(String classpathResource, File serverWorkingDirectory) throws IOException { @@ -150,24 +144,24 @@ public class GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTe } @AfterClass - public static void tearDown() { + public static void stopGemFireServer() { - serverProcess.shutdown(); + gemfireServer.shutdown(); if (Boolean.valueOf(System.getProperty("spring.gemfire.fork.clean", Boolean.TRUE.toString()))) { - org.springframework.util.FileSystemUtils.deleteRecursively(serverProcess.getWorkingDirectory()); + org.springframework.util.FileSystemUtils.deleteRecursively(gemfireServer.getWorkingDirectory()); } } - protected void assertRegion(Region actualRegion, String expectedRegionName) { + @SuppressWarnings("unchecked") + private void assertRegion(Region actualRegion, String expectedRegionName) { - assertThat(actualRegion, is(not(nullValue()))); - assertThat(actualRegion.getName(), is(equalTo(expectedRegionName))); - assertThat(actualRegion.getFullPath(), is(equalTo(String.format("%1$s%2$s", - Region.SEPARATOR, expectedRegionName)))); - assertThat(gemfireClientCache.getRegion(actualRegion.getFullPath()), is(sameInstance(actualRegion))); - assertThat(applicationContext.containsBean(expectedRegionName), is(true)); - assertThat(applicationContext.getBean(expectedRegionName, Region.class), is(sameInstance(actualRegion))); + Assertions.assertThat(actualRegion).isNotNull(); + Assertions.assertThat(actualRegion.getName()).isEqualTo(expectedRegionName); + Assertions.assertThat(actualRegion.getFullPath()).isEqualTo(GemfireUtils.toRegionPath(expectedRegionName)); + Assertions.assertThat(gemfireClientCache.getRegion(actualRegion.getFullPath())).isSameAs(actualRegion); + Assertions.assertThat(applicationContext.containsBean(expectedRegionName)).isTrue(); + Assertions.assertThat(applicationContext.getBean(expectedRegionName, Region.class)).isSameAs(actualRegion); } @Test diff --git a/src/test/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessorTest.java b/src/test/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessorTest.java index a1915287..49ecb67a 100644 --- a/src/test/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessorTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessorTest.java @@ -16,19 +16,31 @@ package org.springframework.data.gemfire.client; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; -import static org.mockito.ArgumentMatchers.*; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.CoreMatchers.sameInstance; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.doAnswer; +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.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.Region; @@ -43,45 +55,52 @@ import org.apache.geode.management.internal.cli.functions.GetRegionsFunction; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.data.gemfire.client.function.ListRegionsOnServerFunction; +import org.springframework.data.gemfire.util.RegionUtils; /** - * The GemfireDataSourcePostProcessor class is a test suite of test cases testing the contract and functionality - * of the GemfireDataSourcePostProcessor class, which is responsible for creating client PROXY Regions - * for all data Regions on servers in a GemFire cluster, providing the ListRegion + * Unit tests for {@link GemfireDataSourcePostProcessor}. * * @author John Blum * @see org.junit.Test * @see org.mockito.Mockito - * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory - * @see org.springframework.data.gemfire.client.GemfireDataSourcePostProcessor * @see org.apache.geode.cache.Region * @see org.apache.geode.cache.client.ClientCache * @see org.apache.geode.cache.client.ClientRegionFactory + * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory + * @see org.springframework.data.gemfire.client.GemfireDataSourcePostProcessor + * @see org.springframework.data.gemfire.client.function.ListRegionsOnServerFunction * @since 1.7.0 */ +@RunWith(MockitoJUnitRunner.class) public class GemfireDataSourcePostProcessorTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); + @Mock + private ClientCache mockClientCache; - protected RegionInformation newRegionInformation(Region region) { + @Rule + public ExpectedException exception = ExpectedException.none(); + + private RegionInformation newRegionInformation(Region region) { return new RegionInformation(region, false); } @SuppressWarnings("unchecked") - protected Region mockRegion(String name) { + private Region mockRegion(String name) { + Region mockRegion = mock(Region.class, name); - RegionAttributes mockRegionAttributes = mock(RegionAttributes.class, - String.format("%1$s-RegionAttributes", name)); + RegionAttributes mockRegionAttributes = + mock(RegionAttributes.class, String.format("%1$s-RegionAttributes", name)); - when(mockRegion.getFullPath()).thenReturn(String.format("%1$s%2$s", Region.SEPARATOR, name)); - when(mockRegion.getName()).thenReturn(name); when(mockRegion.getParentRegion()).thenReturn(null); + when(mockRegion.getFullPath()).thenReturn(RegionUtils.toRegionPath(name)); when(mockRegion.getAttributes()).thenReturn(mockRegionAttributes); when(mockRegionAttributes.getDataPolicy()).thenReturn(DataPolicy.PARTITION); when(mockRegionAttributes.getScope()).thenReturn(Scope.DISTRIBUTED_ACK); @@ -89,26 +108,20 @@ public class GemfireDataSourcePostProcessorTest { return mockRegion; } - protected List asList(Iterable iterable) { - List list = new ArrayList(); - - if (iterable != null) { - for (T element : iterable) { - list.add(element); - } - } - - return list; - } - @Test public void postProcessBeanFactoryCallsCreateClientRegionProxiesWithRegionNames() { - final AtomicBoolean createClientRegionProxiesCalled = new AtomicBoolean(false); - final ConfigurableListableBeanFactory mockBeanFactory = mock(ConfigurableListableBeanFactory.class, "MockSpringBeanFactory"); - final List testRegionNames = Collections.singletonList("Test"); - GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(null) { - @Override Iterable regionNames() { + AtomicBoolean createClientRegionProxiesCalled = new AtomicBoolean(false); + + ConfigurableListableBeanFactory mockBeanFactory = + mock(ConfigurableListableBeanFactory.class, "MockSpringBeanFactory"); + + List testRegionNames = Collections.singletonList("Test"); + + GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache) { + + @Override + Iterable regionNames() { return testRegionNames; } @@ -126,10 +139,13 @@ public class GemfireDataSourcePostProcessorTest { @Test public void regionNamesWithListRegionsOnServerFunction() { - final List expectedRegionNames = Arrays.asList("ExampleOne", "ExampleTwo"); - GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(null) { - @Override @SuppressWarnings("unchecked") T execute(Function gemfireFunction, Object... arguments) { + List expectedRegionNames = Arrays.asList("ExampleOne", "ExampleTwo"); + + GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache) { + + @Override @SuppressWarnings("unchecked") + T execute(Function gemfireFunction, Object... arguments) { assertThat(gemfireFunction, is(instanceOf(ListRegionsOnServerFunction.class))); return (T) expectedRegionNames; } @@ -141,11 +157,16 @@ public class GemfireDataSourcePostProcessorTest { } @Test + @SuppressWarnings("unchecked") public void regionNamesWithGetRegionsFunction() { - final List expectedRegionNames = Arrays.asList("ExampleOne", "ExampleTwo"); - GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(null) { - @Override @SuppressWarnings("unchecked") T execute(Function gemfireFunction, Object... arguments) { + List expectedRegionNames = Arrays.asList("ExampleOne", "ExampleTwo"); + + GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache) { + + @Override @SuppressWarnings("unchecked") + T execute(Function gemfireFunction, Object... arguments) { + if (gemfireFunction instanceof ListRegionsOnServerFunction) { throw new RuntimeException("fail"); } @@ -154,20 +175,25 @@ public class GemfireDataSourcePostProcessorTest { newRegionInformation(mockRegion(expectedRegionNames.get(1)))).toArray(); } - throw new IllegalArgumentException(String.format("GemFire Function (%1$s) with ID (%2$s) not registered", + throw new IllegalArgumentException(String.format("GemFire Function [%1$s] with ID [%2$s] not registered", gemfireFunction.getClass().getName(), gemfireFunction.getId())); } }; - Iterable actualRegionNames = postProcessor.regionNames(); + List actualRegionNames = + StreamSupport.stream(postProcessor.regionNames().spliterator(), false).collect(Collectors.toList()); - assertThat(asList(actualRegionNames).containsAll(expectedRegionNames), is(true)); + assertThat(actualRegionNames.containsAll(expectedRegionNames), is(true)); } @Test public void regionNamesWithGetRegionsFunctionReturningNoResults() { - GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(null) { - @Override @SuppressWarnings("unchecked") T execute(Function gemfireFunction, Object... arguments) { + + GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache) { + + @Override @SuppressWarnings("unchecked") T + execute(Function gemfireFunction, Object... arguments) { + if (gemfireFunction instanceof ListRegionsOnServerFunction) { throw new RuntimeException("fail"); } @@ -189,15 +215,19 @@ public class GemfireDataSourcePostProcessorTest { @Test public void regionNamesWithGetRegionsFunctionThrowingException() { - final AtomicBoolean logMethodCalled = new AtomicBoolean(false); - GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(null) { - @Override @SuppressWarnings("unchecked") T execute(Function gemfireFunction, Object... arguments) { + AtomicBoolean logMethodCalled = new AtomicBoolean(false); + + GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache) { + + @Override @SuppressWarnings("unchecked") T + execute(Function gemfireFunction, Object... arguments) { throw new IllegalArgumentException(String.format("GemFire Function (%1$s) with ID (%2$s) not registered", gemfireFunction.getClass().getName(), gemfireFunction.getId())); } - @Override void log(final String message, final Object... arguments) { + @Override + void log(final String message, final Object... arguments) { assertThat(message.startsWith("Failed to determine the Regions available on the Server:"), is(true)); logMethodCalled.compareAndSet(false, true); } @@ -213,35 +243,40 @@ public class GemfireDataSourcePostProcessorTest { @Test public void containsRegionInformationIsTrue() { - assertThat(new GemfireDataSourcePostProcessor(null).containsRegionInformation( - new Object[] { newRegionInformation(mockRegion("Example")) }), is(true)); + assertThat(new GemfireDataSourcePostProcessor(this.mockClientCache) + .containsRegionInformation(new Object[] { newRegionInformation(mockRegion("Example")) }), + is(true)); } @Test public void containsRegionInformationWithListOfRegionInformationIsFalse() { - assertThat(new GemfireDataSourcePostProcessor(null).containsRegionInformation( - Arrays.asList(newRegionInformation(mockRegion("Example")))), is(false)); + assertThat(new GemfireDataSourcePostProcessor(this.mockClientCache) + .containsRegionInformation(Collections.singletonList(newRegionInformation(mockRegion("Example")))), + is(false)); } @Test public void containsRegionInformationWithNonEmptyArrayContainingNonRegionInformationIsFalse() { - assertThat(new GemfireDataSourcePostProcessor(null).containsRegionInformation(new Object[] { "test" }), - is(false)); + assertThat(new GemfireDataSourcePostProcessor(this.mockClientCache) + .containsRegionInformation(new Object[] { "test" }), is(false)); } @Test public void containsRegionInformationWithEmptyArrayIsFalse() { - assertThat(new GemfireDataSourcePostProcessor(null).containsRegionInformation(new Object[0]), is(false)); + assertThat(new GemfireDataSourcePostProcessor(this.mockClientCache) + .containsRegionInformation(new Object[0]), is(false)); } @Test public void containsRegionInformationWithNullIsFalse() { - assertThat(new GemfireDataSourcePostProcessor(null).containsRegionInformation(null), is(false)); + assertThat(new GemfireDataSourcePostProcessor(this.mockClientCache).containsRegionInformation(null), + is(false)); } @Test @SuppressWarnings("unchecked") public void createClientRegionProxies() { + ClientCache mockClientCache = mock(ClientCache.class, "MockGemFireClientCache"); ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class, "MockGemFireClientRegionFactory"); @@ -283,6 +318,7 @@ public class GemfireDataSourcePostProcessorTest { @Test @SuppressWarnings("unchecked") public void createClientRegionProxiesWhenRegionBeanExists() { + ClientCache mockClientCache = mock(ClientCache.class, "MockGemFireClientCache"); ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class, "MockGemFireClientRegionFactory"); @@ -299,43 +335,10 @@ public class GemfireDataSourcePostProcessorTest { GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(mockClientCache); - postProcessor.createClientRegionProxies(mockBeanFactory, Arrays.asList("Example")); + postProcessor.createClientRegionProxies(mockBeanFactory, Collections.singletonList("Example")); verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.PROXY)); verify(mockClientRegionFactory, never()).create(any(String.class)); verify(mockBeanFactory, never()).registerSingleton(any(String.class), any(Region.class)); } - - @Test - @SuppressWarnings("unchecked") - public void createClientRegionProxiesWhenBeanOfDifferentTypeWithSameNameAsRegionIsRegistered() { - ClientCache mockClientCache = mock(ClientCache.class, "MockGemFireClientCache"); - - ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class, "MockGemFireClientRegionFactory"); - - when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.PROXY))).thenReturn( - mockClientRegionFactory); - - ConfigurableListableBeanFactory mockBeanFactory = mock(ConfigurableListableBeanFactory.class, "MockSpringBeanFactory"); - - when(mockBeanFactory.containsBean(any(String.class))).thenReturn(true); - when(mockBeanFactory.getBean(any(String.class))).thenReturn(new Object()); - - GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(mockClientCache); - - try { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectCause(is(nullValue(Throwable.class))); - expectedException.expectMessage(is(equalTo(String.format( - "Cannot create a client PROXY Region bean named '%1$s'. A bean with this name of type '%2$s' already exists.", - "Example", Object.class.getName())))); - postProcessor.createClientRegionProxies(mockBeanFactory, Arrays.asList("Example")); - } - finally { - verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.PROXY)); - verify(mockClientRegionFactory, never()).create(any(String.class)); - verify(mockBeanFactory, never()).registerSingleton(any(String.class), any(Region.class)); - } - } - } diff --git a/src/test/java/org/springframework/data/gemfire/client/PoolFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/client/PoolFactoryBeanTest.java index f5b31bc5..707ec10c 100644 --- a/src/test/java/org/springframework/data/gemfire/client/PoolFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/PoolFactoryBeanTest.java @@ -68,11 +68,11 @@ public class PoolFactoryBeanTest { @Rule public ExpectedException exception = ExpectedException.none(); - protected ConnectionEndpoint newConnectionEndpoint(String host, int port) { + private ConnectionEndpoint newConnectionEndpoint(String host, int port) { return new ConnectionEndpoint(host, port); } - protected InetSocketAddress newSocketAddress(String host, int port) { + private InetSocketAddress newSocketAddress(String host, int port) { return new InetSocketAddress(host, port); } @@ -89,10 +89,14 @@ public class PoolFactoryBeanTest { when(mockPoolFactory.create(eq("GemFirePool"))).thenReturn(mockPool); PoolFactoryBean poolFactoryBean = new PoolFactoryBean() { - @Override protected PoolFactory createPoolFactory() { + + @Override + protected PoolFactory createPoolFactory() { return mockPoolFactory; } - @Override boolean isDistributedSystemPresent() { + + @Override + boolean isClientCachePresent() { return false; } }; @@ -229,7 +233,7 @@ public class PoolFactoryBeanTest { PoolFactoryBean poolFactoryBean = new PoolFactoryBean(); - ReflectionUtils.setField(PoolFactoryBean.class.getDeclaredField("springBasedPool"), poolFactoryBean, false); + ReflectionUtils.setField(PoolFactoryBean.class.getDeclaredField("springManagedPool"), poolFactoryBean, false); poolFactoryBean.setPool(mockPool); poolFactoryBean.destroy(); @@ -287,7 +291,7 @@ public class PoolFactoryBeanTest { assertThat(poolFactoryBean.getLocators().size(), is(equalTo(1))); assertThat(poolFactoryBean.getLocators().findOne("localhost"), is(equalTo(localhost))); - poolFactoryBean.setLocators(Collections.emptyList()); + poolFactoryBean.setLocators(Collections.emptyList()); assertThat(poolFactoryBean.getLocators(), is(notNullValue())); assertThat(poolFactoryBean.getLocators().isEmpty(), is(true)); @@ -323,7 +327,7 @@ public class PoolFactoryBeanTest { assertThat(poolFactoryBean.getServers().size(), is(equalTo(1))); assertThat(poolFactoryBean.getServers().findOne("localhost"), is(equalTo(localhost))); - poolFactoryBean.setServers(Collections.emptyList()); + poolFactoryBean.setServers(Collections.emptyList()); assertThat(poolFactoryBean.getServers(), is(notNullValue())); assertThat(poolFactoryBean.getServers().isEmpty(), is(true)); @@ -444,7 +448,7 @@ public class PoolFactoryBeanTest { exception.expect(IllegalStateException.class); exception.expectCause(is(nullValue(Throwable.class))); - exception.expectMessage("The Pool has not been initialized"); + exception.expectMessage("Pool [null] has not been initialized"); new PoolFactoryBean().getPool().getPendingEventCount(); } @@ -476,7 +480,7 @@ public class PoolFactoryBeanTest { exception.expect(IllegalStateException.class); exception.expectCause(is(nullValue(Throwable.class))); - exception.expectMessage("The Pool has not been initialized"); + exception.expectMessage("Pool [null] has not been initialized"); new PoolFactoryBean().getPool().getQueryService(); } @@ -511,7 +515,9 @@ public class PoolFactoryBeanTest { AtomicBoolean destroyCalled = new AtomicBoolean(false); PoolFactoryBean poolFactoryBean = new PoolFactoryBean() { - @Override public void destroy() throws Exception { + + @Override + public void destroy() throws Exception { destroyCalled.set(true); throw new IllegalStateException("test"); } @@ -559,7 +565,7 @@ public class PoolFactoryBeanTest { exception.expect(IllegalStateException.class); exception.expectCause(is(nullValue(Throwable.class))); - exception.expectMessage("The Pool has not been initialized"); + exception.expectMessage("Pool [null] has not been initialized"); pool.releaseThreadLocalConnection(); } diff --git a/src/test/java/org/springframework/data/gemfire/client/SpELExpressionConfiguredPoolsIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/client/SpELExpressionConfiguredPoolsIntegrationTests.java index 52da077c..c6528f87 100644 --- a/src/test/java/org/springframework/data/gemfire/client/SpELExpressionConfiguredPoolsIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/client/SpELExpressionConfiguredPoolsIntegrationTests.java @@ -237,7 +237,7 @@ public class SpELExpressionConfiguredPoolsIntegrationTests { } @Override - boolean isDistributedSystemPresent() { + boolean isClientCachePresent() { return true; } } diff --git a/src/test/java/org/springframework/data/gemfire/client/support/DefaultableDelegatingPoolAdapterTest.java b/src/test/java/org/springframework/data/gemfire/client/support/DefaultableDelegatingPoolAdapterTest.java index 2b959293..d2d09c24 100644 --- a/src/test/java/org/springframework/data/gemfire/client/support/DefaultableDelegatingPoolAdapterTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/support/DefaultableDelegatingPoolAdapterTest.java @@ -32,6 +32,7 @@ import static org.mockito.Mockito.when; import java.net.InetSocketAddress; import java.util.Collections; import java.util.List; +import java.util.function.Supplier; import org.apache.geode.cache.client.Pool; import org.apache.geode.cache.query.QueryService; @@ -72,7 +73,7 @@ public class DefaultableDelegatingPoolAdapterTest { private QueryService mockQueryService; @Mock - private DefaultableDelegatingPoolAdapter.ValueProvider mockValueProvider; + private Supplier mockSupplier; private static InetSocketAddress newSocketAddress(String host, int port) { return new InetSocketAddress(host, port); @@ -125,7 +126,7 @@ public class DefaultableDelegatingPoolAdapterTest { exception.expect(IllegalArgumentException.class); exception.expectCause(is(nullValue(Throwable.class))); - exception.expectMessage("'delegate' must not be null"); + exception.expectMessage("Pool delegate must not be null"); DefaultableDelegatingPoolAdapter.from(null); } @@ -154,10 +155,10 @@ public class DefaultableDelegatingPoolAdapterTest { this.poolAdapter = this.poolAdapter.preferDefault(); assertThat(this.poolAdapter.prefersDefault(), is(true)); - assertThat(this.poolAdapter.defaultIfNull("default", this.mockValueProvider), + assertThat(this.poolAdapter.defaultIfNull("default", this.mockSupplier), is(equalTo("default"))); - verifyZeroInteractions(this.mockValueProvider); + verifyZeroInteractions(this.mockSupplier); } @Test @@ -166,13 +167,13 @@ public class DefaultableDelegatingPoolAdapterTest { this.poolAdapter = this.poolAdapter.preferDefault(); - when(this.mockValueProvider.getValue()).thenReturn("pool"); + when(this.mockSupplier.get()).thenReturn("pool"); assertThat(this.poolAdapter.prefersDefault(), is(true)); - assertThat(this.poolAdapter.defaultIfNull(null, this.mockValueProvider), + assertThat(this.poolAdapter.defaultIfNull(null, this.mockSupplier), is(equalTo("pool"))); - verify(this.mockValueProvider, times(1)).getValue(); + verify(this.mockSupplier, times(1)).get(); } @Test @@ -181,13 +182,13 @@ public class DefaultableDelegatingPoolAdapterTest { this.poolAdapter = this.poolAdapter.preferPool(); - when(mockValueProvider.getValue()).thenReturn("pool"); + when(mockSupplier.get()).thenReturn("pool"); assertThat(this.poolAdapter.prefersPool(), is(true)); - assertThat(this.poolAdapter.defaultIfNull("default", this.mockValueProvider), + assertThat(this.poolAdapter.defaultIfNull("default", this.mockSupplier), is(equalTo("pool"))); - verify(this.mockValueProvider, times(1)).getValue(); + verify(this.mockSupplier, times(1)).get(); } @Test @@ -196,13 +197,13 @@ public class DefaultableDelegatingPoolAdapterTest { this.poolAdapter = this.poolAdapter.preferPool(); - when(this.mockValueProvider.getValue()).thenReturn(null); + when(this.mockSupplier.get()).thenReturn(null); assertThat(this.poolAdapter.prefersPool(), is(true)); - assertThat(this.poolAdapter.defaultIfNull("default", this.mockValueProvider), + assertThat(this.poolAdapter.defaultIfNull("default", this.mockSupplier), is(equalTo("default"))); - verify(this.mockValueProvider, times(1)).getValue(); + verify(this.mockSupplier, times(1)).get(); } @Test @@ -214,9 +215,9 @@ public class DefaultableDelegatingPoolAdapterTest { List defaultList = Collections.singletonList("default"); assertThat(this.poolAdapter.prefersDefault(), is(true)); - assertThat((List) this.poolAdapter.defaultIfEmpty(defaultList, this.mockValueProvider), is(equalTo(defaultList))); + assertThat((List) this.poolAdapter.defaultIfEmpty(defaultList, this.mockSupplier), is(equalTo(defaultList))); - verifyZeroInteractions(this.mockValueProvider); + verifyZeroInteractions(this.mockSupplier); } @Test @@ -227,12 +228,12 @@ public class DefaultableDelegatingPoolAdapterTest { List poolList = Collections.singletonList("pool"); - when(this.mockValueProvider.getValue()).thenReturn(poolList); + when(this.mockSupplier.get()).thenReturn(poolList); assertThat(this.poolAdapter.prefersDefault(), is(true)); - assertThat((List) this.poolAdapter.defaultIfEmpty(null, this.mockValueProvider), is(equalTo(poolList))); + assertThat((List) this.poolAdapter.defaultIfEmpty(null, this.mockSupplier), is(equalTo(poolList))); - verify(this.mockValueProvider, times(1)).getValue(); + verify(this.mockSupplier, times(1)).get(); } @Test @@ -243,13 +244,13 @@ public class DefaultableDelegatingPoolAdapterTest { List poolList = Collections.singletonList("pool"); - when(this.mockValueProvider.getValue()).thenReturn(poolList); + when(this.mockSupplier.get()).thenReturn(poolList); assertThat(this.poolAdapter.prefersDefault(), is(true)); - assertThat((List) this.poolAdapter.defaultIfEmpty(Collections.emptyList(), this.mockValueProvider), + assertThat((List) this.poolAdapter.defaultIfEmpty(Collections.emptyList(), this.mockSupplier), is(equalTo(poolList))); - verify(this.mockValueProvider, times(1)).getValue(); + verify(this.mockSupplier, times(1)).get(); } @Test @@ -260,13 +261,13 @@ public class DefaultableDelegatingPoolAdapterTest { List poolList = Collections.singletonList("pool"); - when(this.mockValueProvider.getValue()).thenReturn(poolList); + when(this.mockSupplier.get()).thenReturn(poolList); assertThat(this.poolAdapter.prefersPool(), is(true)); - assertThat((List) this.poolAdapter.defaultIfEmpty(Collections.singletonList("default"), this.mockValueProvider), + assertThat((List) this.poolAdapter.defaultIfEmpty(Collections.singletonList("default"), this.mockSupplier), is(equalTo(poolList))); - verify(this.mockValueProvider, times(1)).getValue(); + verify(this.mockSupplier, times(1)).get(); } @Test @@ -275,15 +276,15 @@ public class DefaultableDelegatingPoolAdapterTest { this.poolAdapter = this.poolAdapter.preferPool(); - when(this.mockValueProvider.getValue()).thenReturn(null); + when(this.mockSupplier.get()).thenReturn(null); List defaultList = Collections.singletonList("default"); assertThat(this.poolAdapter.prefersPool(), is(true)); - assertThat((List) this.poolAdapter.defaultIfEmpty(defaultList, this.mockValueProvider), + assertThat((List) this.poolAdapter.defaultIfEmpty(defaultList, this.mockSupplier), is(equalTo(defaultList))); - verify(this.mockValueProvider, times(1)).getValue(); + verify(this.mockSupplier, times(1)).get(); } @Test @@ -292,15 +293,15 @@ public class DefaultableDelegatingPoolAdapterTest { assertThat(this.poolAdapter.preferPool(), is(sameInstance(this.poolAdapter))); - when(this.mockValueProvider.getValue()).thenReturn(Collections.emptyList()); + when(this.mockSupplier.get()).thenReturn(Collections.emptyList()); List defaultList = Collections.singletonList("default"); assertThat(this.poolAdapter.prefersPool(), is(true)); - assertThat((List) this.poolAdapter.defaultIfEmpty(defaultList, this.mockValueProvider), + assertThat((List) this.poolAdapter.defaultIfEmpty(defaultList, this.mockSupplier), is(equalTo(defaultList))); - verify(this.mockValueProvider, times(1)).getValue(); + verify(this.mockSupplier, times(1)).get(); } @Test diff --git a/src/test/java/org/springframework/data/gemfire/config/xml/CacheNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/xml/CacheNamespaceTest.java index 0fc306a0..9f7e2030 100644 --- a/src/test/java/org/springframework/data/gemfire/config/xml/CacheNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/xml/CacheNamespaceTest.java @@ -16,13 +16,10 @@ package org.springframework.data.gemfire.config.xml; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.springframework.data.gemfire.support.GemfireBeanFactoryLocator.newBeanFactoryLocator; @@ -42,7 +39,6 @@ import org.springframework.data.gemfire.TestUtils; import org.springframework.data.gemfire.client.ClientCacheFactoryBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.util.ReflectionTestUtils; /** * Unit tests for {@link CacheParser}. @@ -68,26 +64,30 @@ public class CacheNamespaceTest{ public void testNoNamedCache() throws Exception { assertTrue(applicationContext.containsBean("gemfireCache")); - assertTrue(applicationContext.containsBean("gemfire-cache")); // assert alias is registered + assertTrue(applicationContext.containsBean("gemfire-cache")); + + CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&gemfireCache", CacheFactoryBean.class); + + assertNull(cacheFactoryBean.getCacheXml()); + + Properties gemfireProperties = cacheFactoryBean.getProperties(); + + assertNotNull(gemfireProperties); + assertFalse(cacheFactoryBean.getEnableAutoReconnect()); + assertTrue(gemfireProperties.containsKey("disable-auto-reconnect")); + assertTrue(Boolean.parseBoolean(gemfireProperties.getProperty("disable-auto-reconnect"))); + assertFalse(cacheFactoryBean.getUseClusterConfiguration()); + assertTrue(gemfireProperties.containsKey("use-cluster-configuration")); + assertFalse(Boolean.parseBoolean(gemfireProperties.getProperty("use-cluster-configuration"))); Cache gemfireCache = applicationContext.getBean("gemfireCache", Cache.class); assertNotNull(gemfireCache); assertNotNull(gemfireCache.getDistributedSystem()); assertNotNull(gemfireCache.getDistributedSystem().getProperties()); + assertNotNull(gemfireCache.getDistributedSystem().getProperties().containsKey("disable-auto-reconnect")); assertTrue(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() .getProperty("disable-auto-reconnect"))); - - CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&gemfireCache", CacheFactoryBean.class); - - assertNull(TestUtils.readField("cacheXml", cacheFactoryBean)); - - Properties gemfireProperties = cacheFactoryBean.getProperties(); - - assertNotNull(gemfireProperties); - assertTrue(gemfireProperties.containsKey("disable-auto-reconnect")); - assertTrue(Boolean.parseBoolean(gemfireProperties.getProperty("disable-auto-reconnect"))); - assertFalse(cacheFactoryBean.getEnableAutoReconnect()); } @Test @@ -95,39 +95,60 @@ public class CacheNamespaceTest{ assertTrue(applicationContext.containsBean("cache-with-name")); + CacheFactoryBean cacheFactoryBean = + applicationContext.getBean("&cache-with-name", CacheFactoryBean.class); + + assertNull(cacheFactoryBean.getCacheXml()); + + Properties gemfireProperties = cacheFactoryBean.getProperties(); + + assertNotNull(gemfireProperties); + assertFalse(cacheFactoryBean.getEnableAutoReconnect()); + assertTrue(gemfireProperties.containsKey("disable-auto-reconnect")); + assertTrue(Boolean.parseBoolean(gemfireProperties.getProperty("disable-auto-reconnect"))); + assertFalse(cacheFactoryBean.getUseClusterConfiguration()); + assertTrue(gemfireProperties.containsKey("use-cluster-configuration")); + assertFalse(Boolean.parseBoolean(gemfireProperties.getProperty("use-cluster-configuration"))); + Cache gemfireCache = applicationContext.getBean("gemfireCache", Cache.class); assertTrue(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() .getProperty("disable-auto-reconnect"))); - CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&cache-with-name", CacheFactoryBean.class); - - assertNull(TestUtils.readField("cacheXml", cacheFactoryBean)); - - Properties gemfireProperties = cacheFactoryBean.getProperties(); - - assertNotNull(gemfireProperties); - assertTrue(gemfireProperties.containsKey("disable-auto-reconnect")); - assertTrue(Boolean.parseBoolean(gemfireProperties.getProperty("disable-auto-reconnect"))); - assertFalse(cacheFactoryBean.getEnableAutoReconnect()); + assertFalse(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() + .getProperty("use-cluster-configuration"))); } @Test - public void testCacheWithXmlAndProperties() throws Exception { + public void testCacheWithAutoReconnectDisabled() throws Exception { - assertTrue(applicationContext.containsBean("cache-with-xml-and-props")); + assertTrue(applicationContext.containsBean("cache-with-auto-reconnect-disabled")); - CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&cache-with-xml-and-props", CacheFactoryBean.class); + CacheFactoryBean cacheFactoryBean = + applicationContext.getBean("&cache-with-auto-reconnect-disabled", CacheFactoryBean.class); - Resource cacheXmlResource = TestUtils.readField("cacheXml", cacheFactoryBean); + assertFalse(cacheFactoryBean.getEnableAutoReconnect()); - assertEquals("gemfire-cache.xml", cacheXmlResource.getFilename()); - assertTrue(applicationContext.containsBean("gemfireProperties")); - assertEquals(applicationContext.getBean("gemfireProperties"), TestUtils.readField("properties", cacheFactoryBean)); - assertEquals(Boolean.TRUE, TestUtils.readField("pdxReadSerialized", cacheFactoryBean)); - assertEquals(Boolean.FALSE, TestUtils.readField("pdxIgnoreUnreadFields", cacheFactoryBean)); - assertEquals(Boolean.TRUE, TestUtils.readField("pdxPersistent", cacheFactoryBean)); + Cache gemfireCache = applicationContext.getBean("cache-with-auto-reconnect-disabled", Cache.class); + assertTrue(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() + .getProperty("disable-auto-reconnect"))); + } + + @Test + public void testCacheWithAutoReconnectEnabled() throws Exception { + + assertTrue(applicationContext.containsBean("cache-with-auto-reconnect-enabled")); + + CacheFactoryBean cacheFactoryBean = + applicationContext.getBean("&cache-with-auto-reconnect-enabled", CacheFactoryBean.class); + + assertTrue(cacheFactoryBean.getEnableAutoReconnect()); + + Cache gemfireCache = applicationContext.getBean("cache-with-auto-reconnect-enabled", Cache.class); + + assertFalse(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() + .getProperty("disable-auto-reconnect"))); } @Test @@ -138,36 +159,68 @@ public class CacheNamespaceTest{ assertTrue(cache.getGatewayConflictResolver() instanceof TestGatewayConflictResolver); } - @Test - public void testCacheWithAutoReconnectDisabled() throws Exception { + @Test(expected = IllegalStateException.class) + public void testCacheWithNoBeanFactoryLocator() throws Exception { - assertTrue(applicationContext.containsBean("cache-with-auto-reconnect-disabled")); - - Cache gemfireCache = applicationContext.getBean("cache-with-auto-reconnect-disabled", Cache.class); - - assertTrue(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() - .getProperty("disable-auto-reconnect"))); + assertTrue(applicationContext.containsBean("cache-with-no-bean-factory-locator")); CacheFactoryBean cacheFactoryBean = - applicationContext.getBean("&cache-with-auto-reconnect-disabled", CacheFactoryBean.class); + applicationContext.getBean("&cache-with-no-bean-factory-locator", CacheFactoryBean.class); - assertFalse(cacheFactoryBean.getEnableAutoReconnect()); + assertNull(cacheFactoryBean.getBeanFactoryLocator()); + + newBeanFactoryLocator().useBeanFactory("cache-with-no-bean-factory-locator"); } @Test - public void testCacheWithAutoReconnectEnabled() throws Exception { + public void testCacheWithUseClusterConfigurationDisabled() { - assertTrue(applicationContext.containsBean("cache-with-auto-reconnect-enabled")); - - Cache gemfireCache = applicationContext.getBean("cache-with-auto-reconnect-enabled", Cache.class); - - assertFalse(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() - .getProperty("disable-auto-reconnect"))); + assertTrue(applicationContext.containsBean("cache-with-use-cluster-configuration-disabled")); CacheFactoryBean cacheFactoryBean = - applicationContext.getBean("&cache-with-auto-reconnect-enabled", CacheFactoryBean.class); + applicationContext.getBean("&cache-with-use-cluster-configuration-disabled", CacheFactoryBean.class); - assertTrue(cacheFactoryBean.getEnableAutoReconnect()); + assertFalse(cacheFactoryBean.getEnableAutoReconnect()); + + Cache gemfireCache = + applicationContext.getBean("cache-with-use-cluster-configuration-disabled", Cache.class); + + assertFalse(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() + .getProperty("use-cluster-configuration"))); + } + + @Test + public void testCacheWithUseClusterConfigurationEnabled() { + + assertTrue(applicationContext.containsBean("cache-with-use-cluster-configuration-enabled")); + + CacheFactoryBean cacheFactoryBean = + applicationContext.getBean("&cache-with-use-cluster-configuration-enabled", CacheFactoryBean.class); + + assertTrue(cacheFactoryBean.getUseClusterConfiguration()); + + Cache gemfireCache = + applicationContext.getBean("cache-with-use-cluster-configuration-enabled", Cache.class); + + assertTrue(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties() + .getProperty("use-cluster-configuration"))); + } + + @Test + public void testCacheWithXmlAndProperties() throws Exception { + + assertTrue(applicationContext.containsBean("cache-with-xml-and-props")); + + CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&cache-with-xml-and-props", CacheFactoryBean.class); + + Resource cacheXmlResource = cacheFactoryBean.getCacheXml(); + + assertEquals("gemfire-cache.xml", cacheXmlResource.getFilename()); + assertTrue(applicationContext.containsBean("gemfireProperties")); + assertEquals(applicationContext.getBean("gemfireProperties"), TestUtils.readField("properties", cacheFactoryBean)); + assertEquals(Boolean.TRUE, TestUtils.readField("pdxReadSerialized", cacheFactoryBean)); + assertEquals(Boolean.FALSE, TestUtils.readField("pdxIgnoreUnreadFields", cacheFactoryBean)); + assertEquals(Boolean.TRUE, TestUtils.readField("pdxPersistent", cacheFactoryBean)); } @Test @@ -175,7 +228,8 @@ public class CacheNamespaceTest{ assertTrue(applicationContext.containsBean("heap-tuned-cache")); - CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&heap-tuned-cache", CacheFactoryBean.class); + CacheFactoryBean cacheFactoryBean = + applicationContext.getBean("&heap-tuned-cache", CacheFactoryBean.class); Float criticalHeapPercentage = cacheFactoryBean.getCriticalHeapPercentage(); Float evictionHeapPercentage = cacheFactoryBean.getEvictionHeapPercentage(); @@ -189,7 +243,8 @@ public class CacheNamespaceTest{ assertTrue(applicationContext.containsBean("off-heap-tuned-cache")); - CacheFactoryBean cacheFactoryBean = applicationContext.getBean("&off-heap-tuned-cache", CacheFactoryBean.class); + CacheFactoryBean cacheFactoryBean = + applicationContext.getBean("&off-heap-tuned-cache", CacheFactoryBean.class); Float criticalOffHeapPercentage = cacheFactoryBean.getCriticalOffHeapPercentage(); Float evictionOffHeapPercentage = cacheFactoryBean.getEvictionOffHeapPercentage(); @@ -198,33 +253,16 @@ public class CacheNamespaceTest{ assertEquals(50.0f, evictionOffHeapPercentage, 0.0001); } - @Test(expected = IllegalStateException.class) - public void testNoBeanFactoryLocator() throws Exception { - - assertTrue(applicationContext.containsBean("no-bean-factory-locator-cache")); - - CacheFactoryBean cacheFactoryBean = - applicationContext.getBean("&no-bean-factory-locator-cache", CacheFactoryBean.class); - - assertThat(ReflectionTestUtils.getField(cacheFactoryBean, "beanFactoryLocator"), is(nullValue())); - - newBeanFactoryLocator().useBeanFactory("no-bean-factory-locator-cache"); - } - @Test - public void namedClientCacheWithNoProperties() throws Exception { + public void namedClientCacheWithNoPropertiesAndNoCacheXml() throws Exception { assertTrue(applicationContext.containsBean("client-cache-with-name")); ClientCacheFactoryBean clientCacheFactoryBean = applicationContext.getBean("&client-cache-with-name", ClientCacheFactoryBean.class); - assertNull(TestUtils.readField("cacheXml", clientCacheFactoryBean)); - - Properties gemfireProperties = clientCacheFactoryBean.getProperties(); - - assertNotNull(gemfireProperties); - assertTrue(gemfireProperties.isEmpty()); + assertNull(clientCacheFactoryBean.getCacheXml()); + assertNull(clientCacheFactoryBean.getProperties()); } @Test @@ -235,14 +273,11 @@ public class CacheNamespaceTest{ ClientCacheFactoryBean clientCacheFactoryBean = applicationContext.getBean("&client-cache-with-xml", ClientCacheFactoryBean.class); - Resource cacheXmlResource = TestUtils.readField("cacheXml", clientCacheFactoryBean); + Resource cacheXmlResource = clientCacheFactoryBean.getCacheXml(); assertEquals("gemfire-client-cache.xml", cacheXmlResource.getFilename()); - Properties gemfireProperties = clientCacheFactoryBean.getProperties(); - - assertNotNull(gemfireProperties); - assertTrue(gemfireProperties.isEmpty()); + assertNull(clientCacheFactoryBean.getProperties()); } public static class TestGatewayConflictResolver implements GatewayConflictResolver { diff --git a/src/test/java/org/springframework/data/gemfire/config/xml/ClientRegionNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/xml/ClientRegionNamespaceTest.java index 23326621..55ada728 100644 --- a/src/test/java/org/springframework/data/gemfire/config/xml/ClientRegionNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/xml/ClientRegionNamespaceTest.java @@ -23,17 +23,12 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; import java.io.File; -import java.util.concurrent.atomic.AtomicReference; import org.apache.geode.cache.CacheListener; import org.apache.geode.cache.CacheLoader; @@ -47,16 +42,12 @@ import org.apache.geode.cache.InterestResultPolicy; import org.apache.geode.cache.LoaderHelper; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionAttributes; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.ClientRegionFactory; import org.apache.geode.cache.client.ClientRegionShortcut; import org.apache.geode.cache.util.CacheWriterAdapter; import org.apache.geode.compression.Compressor; import org.junit.AfterClass; import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.data.gemfire.SimpleCacheListener; @@ -64,6 +55,7 @@ import org.springframework.data.gemfire.SimpleObjectSizer; import org.springframework.data.gemfire.TestUtils; import org.springframework.data.gemfire.client.ClientRegionFactoryBean; import org.springframework.data.gemfire.client.Interest; +import org.springframework.data.gemfire.test.mock.context.GemFireMockObjectsApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.ObjectUtils; @@ -80,7 +72,7 @@ import org.springframework.util.ObjectUtils; * @see org.springframework.data.gemfire.config.xml.ClientRegionParser */ @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="client-ns.xml") +@ContextConfiguration(locations="client-ns.xml", initializers = GemFireMockObjectsApplicationContextInitializer.class) @SuppressWarnings("unused") public class ClientRegionNamespaceTest { @@ -95,6 +87,7 @@ public class ClientRegionNamespaceTest { @Test public void testBeanNames() throws Exception { + assertTrue(applicationContext.containsBean("SimpleRegion")); assertTrue(applicationContext.containsBean("Publisher")); assertTrue(applicationContext.containsBean("ComplexRegion")); @@ -105,6 +98,7 @@ public class ClientRegionNamespaceTest { @Test public void testSimpleClientRegion() throws Exception { + assertTrue(applicationContext.containsBean("simple")); Region simple = applicationContext.getBean("simple", Region.class); @@ -119,6 +113,7 @@ public class ClientRegionNamespaceTest { @Test @SuppressWarnings("rawtypes") public void testPublishingClientRegion() throws Exception { + assertTrue(applicationContext.containsBean("empty")); ClientRegionFactoryBean emptyClientRegionFactoryBean = applicationContext @@ -134,6 +129,7 @@ public class ClientRegionNamespaceTest { @Test @SuppressWarnings("rawtypes") public void testComplexClientRegion() throws Exception { + assertTrue(applicationContext.containsBean("complex")); ClientRegionFactoryBean complexClientRegionFactoryBean = applicationContext @@ -161,6 +157,7 @@ public class ClientRegionNamespaceTest { @Test @SuppressWarnings({ "deprecation", "rawtypes" }) public void testPersistentClientRegion() throws Exception { + assertTrue(applicationContext.containsBean("persistent")); Region persistent = applicationContext.getBean("persistent", Region.class); @@ -179,6 +176,7 @@ public class ClientRegionNamespaceTest { @Test @SuppressWarnings("rawtypes") public void testOverflowClientRegion() throws Exception { + assertTrue(applicationContext.containsBean("overflow")); ClientRegionFactoryBean overflowClientRegionFactoryBean = applicationContext @@ -204,6 +202,7 @@ public class ClientRegionNamespaceTest { @Test public void testClientRegionWithCacheLoaderAndCacheWriter() throws Exception { + assertTrue(applicationContext.containsBean("loadWithWrite")); ClientRegionFactoryBean factory = applicationContext.getBean("&loadWithWrite", ClientRegionFactoryBean.class); @@ -217,6 +216,7 @@ public class ClientRegionNamespaceTest { @Test public void testCompressedReplicateRegion() { + assertTrue(applicationContext.containsBean("Compressed")); Region compressed = applicationContext.getBean("Compressed", Region.class); @@ -276,7 +276,7 @@ public class ClientRegionNamespaceTest { assertInterest(true, false, InterestResultPolicy.KEYS, getInterestWithKey(".*", interests)); assertInterest(true, false, InterestResultPolicy.KEYS_VALUES, getInterestWithKey("keyPrefix.*", interests)); - Region mockClientRegion = MockCacheFactoryBean.MOCK_REGION_REF.get(); + Region mockClientRegion = applicationContext.getBean("client-with-interests", Region.class); assertNotNull(mockClientRegion); @@ -287,15 +287,17 @@ public class ClientRegionNamespaceTest { eq(InterestResultPolicy.KEYS_VALUES), eq(true), eq(false)); } - protected void assertInterest(final boolean expectedDurable, final boolean expectedReceiveValues, - final InterestResultPolicy expectedPolicy, final Interest actualInterest) { + private void assertInterest(boolean expectedDurable, boolean expectedReceiveValues, + InterestResultPolicy expectedPolicy, Interest actualInterest) { + assertNotNull(actualInterest); assertEquals(expectedDurable, actualInterest.isDurable()); assertEquals(expectedReceiveValues, actualInterest.isReceiveValues()); assertEquals(expectedPolicy, actualInterest.getPolicy()); } - protected Interest getInterestWithKey(final String key, final Interest... interests) { + private Interest getInterestWithKey(final String key, final Interest... interests) { + for (Interest interest : interests) { if (interest.getKey().equals(key)) { return interest; @@ -305,43 +307,6 @@ public class ClientRegionNamespaceTest { return null; } - static final class MockCacheFactoryBean implements FactoryBean, InitializingBean { - - static final AtomicReference MOCK_REGION_REF = new AtomicReference(null); - - private ClientCache mockClientCache; - - @Override - @SuppressWarnings("unchecked") - public void afterPropertiesSet() throws Exception { - this.mockClientCache = mock(ClientCache.class, - ClientRegionNamespaceTest.class.getSimpleName().concat(".MockClientCache")); - - ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class, - ClientRegionNamespaceTest.class.getSimpleName().concat("MockClientRegionFactory")); - - when(this.mockClientCache.createClientRegionFactory(any(ClientRegionShortcut.class))) - .thenReturn(mockClientRegionFactory); - - Region mockRegion = mock(Region.class, - ClientRegionNamespaceTest.class.getSimpleName().concat(".MockClientRegion")); - - when(mockClientRegionFactory.create(anyString())).thenReturn(mockRegion); - - MOCK_REGION_REF.compareAndSet(null, mockRegion); - } - - @Override - public ClientCache getObject() throws Exception { - return this.mockClientCache; - } - - @Override - public Class getObjectType() { - return ClientCache.class; - } - } - public static final class TestCacheLoader implements CacheLoader { @Override @@ -350,12 +315,11 @@ public class ClientRegionNamespaceTest { } @Override - public void close() { - } + public void close() { } + } - public static final class TestCacheWriter extends CacheWriterAdapter { - } + public static final class TestCacheWriter extends CacheWriterAdapter { } public static class TestCompressor implements Compressor { diff --git a/src/test/java/org/springframework/data/gemfire/config/xml/InvalidRegionDefinitionUsingBeansNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/xml/InvalidRegionDefinitionUsingBeansNamespaceTest.java index e8bd71b3..eca90c42 100644 --- a/src/test/java/org/springframework/data/gemfire/config/xml/InvalidRegionDefinitionUsingBeansNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/xml/InvalidRegionDefinitionUsingBeansNamespaceTest.java @@ -42,18 +42,21 @@ public class InvalidRegionDefinitionUsingBeansNamespaceTest { @Test(expected = IllegalArgumentException.class) public void testInvalidDataPolicyPersistentAttributeSettings() { + try { new ClassPathXmlApplicationContext(CONFIG_LOCATION); } catch (BeanCreationException expected) { + assertTrue(expected.getCause() instanceof IllegalArgumentException); - assertEquals("Data Policy [REPLICATE] is invalid when persistent is true.", expected.getCause().getMessage()); + assertEquals("Data Policy [REPLICATE] is not valid when persistent is true", + expected.getCause().getMessage()); throw (IllegalArgumentException) expected.getCause(); } } @SuppressWarnings("unused") - public static final class TestRegionFactoryBean extends RegionFactoryBean { - } + public static final class TestRegionFactoryBean extends RegionFactoryBean { } + } diff --git a/src/test/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionNamespaceTest.java index bc4c6875..fe9540cc 100644 --- a/src/test/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionNamespaceTest.java @@ -62,13 +62,15 @@ import org.springframework.util.ObjectUtils; public class ReplicatedRegionNamespaceTest { @Autowired - private ApplicationContext context; + private ApplicationContext applicationContext; @Test public void testSimpleReplicateRegion() throws Exception { - assertTrue(context.containsBean("simple")); - RegionFactoryBean simpleRegionFactoryBean = context.getBean("&simple", RegionFactoryBean.class); + assertTrue(applicationContext.containsBean("simple")); + + RegionFactoryBean simpleRegionFactoryBean = + applicationContext.getBean("&simple", RegionFactoryBean.class); assertEquals("simple", TestUtils.readField("beanName", simpleRegionFactoryBean)); assertEquals(false, TestUtils.readField("close", simpleRegionFactoryBean)); @@ -85,9 +87,11 @@ public class ReplicatedRegionNamespaceTest { @Test @SuppressWarnings({ "deprecation", "rawtypes" }) public void testPublishReplicateRegion() throws Exception { - assertTrue(context.containsBean("pub")); - RegionFactoryBean publisherRegionFactoryBean = context.getBean("&pub", RegionFactoryBean.class); + assertTrue(applicationContext.containsBean("pub")); + + RegionFactoryBean publisherRegionFactoryBean = + applicationContext.getBean("&pub", RegionFactoryBean.class); assertTrue(publisherRegionFactoryBean instanceof ReplicatedRegionFactoryBean); assertEquals("publisher", TestUtils.readField("name", publisherRegionFactoryBean)); @@ -102,9 +106,11 @@ public class ReplicatedRegionNamespaceTest { @Test @SuppressWarnings("rawtypes") public void testComplexReplicateRegion() throws Exception { - assertTrue(context.containsBean("complex")); - RegionFactoryBean complexRegionFactoryBean = context.getBean("&complex", RegionFactoryBean.class); + assertTrue(applicationContext.containsBean("complex")); + + RegionFactoryBean complexRegionFactoryBean = + applicationContext.getBean("&complex", RegionFactoryBean.class); assertNotNull(complexRegionFactoryBean); assertEquals("complex", TestUtils.readField("beanName", complexRegionFactoryBean)); @@ -113,19 +119,20 @@ public class ReplicatedRegionNamespaceTest { assertFalse(ObjectUtils.isEmpty(cacheListeners)); assertEquals(2, cacheListeners.length); - assertSame(context.getBean("c-listener"), cacheListeners[0]); + assertSame(applicationContext.getBean("c-listener"), cacheListeners[0]); assertTrue(cacheListeners[1] instanceof SimpleCacheListener); assertNotSame(cacheListeners[0], cacheListeners[1]); - assertSame(context.getBean("c-loader"), TestUtils.readField("cacheLoader", complexRegionFactoryBean)); - assertSame(context.getBean("c-writer"), TestUtils.readField("cacheWriter", complexRegionFactoryBean)); + assertSame(applicationContext.getBean("c-loader"), TestUtils.readField("cacheLoader", complexRegionFactoryBean)); + assertSame(applicationContext.getBean("c-writer"), TestUtils.readField("cacheWriter", complexRegionFactoryBean)); } @Test @SuppressWarnings("rawtypes") public void testReplicatedRegionWithAttributes() throws Exception { - assertTrue(context.containsBean("replicated-with-attributes")); - Region region = context.getBean("replicated-with-attributes", Region.class); + assertTrue(applicationContext.containsBean("replicated-with-attributes")); + + Region region = applicationContext.getBean("replicated-with-attributes", Region.class); assertNotNull("The 'replicated-with-attributes' Region was not properly configured and initialized!", region); @@ -151,9 +158,10 @@ public class ReplicatedRegionNamespaceTest { @Test public void testReplicatedWithSynchronousIndexUpdates() { - assertTrue(context.containsBean("replicated-with-synchronous-index-updates")); - Region region = context.getBean("replicated-with-synchronous-index-updates", Region.class); + assertTrue(applicationContext.containsBean("replicated-with-synchronous-index-updates")); + + Region region = applicationContext.getBean("replicated-with-synchronous-index-updates", Region.class); assertNotNull(String.format("The '%1$s' Region was not properly configured and initialized!", "replicated-with-synchronous-index-updates"), region); @@ -167,23 +175,27 @@ public class ReplicatedRegionNamespaceTest { @Test @SuppressWarnings("rawtypes") public void testRegionLookup() throws Exception { - Cache cache = context.getBean(Cache.class); + + Cache cache = applicationContext.getBean(Cache.class); + Region existing = cache.createRegionFactory().create("existing"); - assertTrue(context.containsBean("lookup")); + assertTrue(applicationContext.containsBean("lookup")); - RegionLookupFactoryBean regionLookupFactoryBean = context.getBean("&lookup", RegionLookupFactoryBean.class); + RegionLookupFactoryBean regionLookupFactoryBean = + applicationContext.getBean("&lookup", RegionLookupFactoryBean.class); assertNotNull(regionLookupFactoryBean); assertEquals("existing", TestUtils.readField("name", regionLookupFactoryBean)); - assertSame(existing, context.getBean("lookup")); + assertSame(existing, applicationContext.getBean("lookup")); } @Test public void testCompressedReplicateRegion() { - assertTrue(context.containsBean("Compressed")); - Region compressed = context.getBean("Compressed", Region.class); + assertTrue(applicationContext.containsBean("Compressed")); + + Region compressed = applicationContext.getBean("Compressed", Region.class); assertNotNull("The 'Compressed' REPLICATE Region was not properly configured and initialized!", compressed); assertEquals("Compressed", compressed.getName()); diff --git a/src/test/java/org/springframework/data/gemfire/config/xml/SubRegionWithInvalidDataPolicyTest.java b/src/test/java/org/springframework/data/gemfire/config/xml/SubRegionWithInvalidDataPolicyTest.java index 7a30b954..6f72a552 100644 --- a/src/test/java/org/springframework/data/gemfire/config/xml/SubRegionWithInvalidDataPolicyTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/xml/SubRegionWithInvalidDataPolicyTest.java @@ -39,11 +39,13 @@ public class SubRegionWithInvalidDataPolicyTest { @Test(expected = XmlBeanDefinitionStoreException.class) public void testSubRegionBeanDefinitionWithInconsistentDataPolicy() { + try { new ClassPathXmlApplicationContext( "/org/springframework/data/gemfire/config/xml/subregion-with-invalid-datapolicy.xml"); } catch (XmlBeanDefinitionStoreException expected) { + assertTrue(expected.getCause() instanceof SAXParseException); assertTrue(expected.getCause().getMessage().contains("PERSISTENT_PARTITION")); @@ -53,14 +55,16 @@ public class SubRegionWithInvalidDataPolicyTest { @Test(expected = BeanCreationException.class) public void testSubRegionBeanDefinitionWithInvalidDataPolicyPersistentSettings() { + try { new ClassPathXmlApplicationContext( "/org/springframework/data/gemfire/config/xml/subregion-with-inconsistent-datapolicy-persistent-settings.xml"); } catch (BeanCreationException expected) { + assertTrue(expected.getMessage().contains("Error creating bean with name '/Parent/Child'")); assertTrue(expected.getCause() instanceof IllegalArgumentException); - assertEquals("Data Policy [REPLICATE] is invalid when persistent is true.", + assertEquals("Data Policy [REPLICATE] is not valid when persistent is true", expected.getCause().getMessage()); throw expected; diff --git a/src/test/java/org/springframework/data/gemfire/config/xml/TemplateRegionDefinitionOrderErrorNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/xml/TemplateRegionDefinitionOrderErrorNamespaceTest.java index 403f6915..0f266cdd 100644 --- a/src/test/java/org/springframework/data/gemfire/config/xml/TemplateRegionDefinitionOrderErrorNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/xml/TemplateRegionDefinitionOrderErrorNamespaceTest.java @@ -16,7 +16,7 @@ package org.springframework.data.gemfire.config.xml; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; @@ -37,20 +37,23 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; */ public class TemplateRegionDefinitionOrderErrorNamespaceTest { - protected String getConfigLocation() { + private String getConfigLocation() { return getClass().getName().replace(".", "/").concat("-context.xml"); } @Test(expected = BeanDefinitionParsingException.class) public void testIncorrectTemplateRegionDefinitionOrder() throws Exception { + try { new ClassPathXmlApplicationContext(getConfigLocation()); } catch (BeanDefinitionParsingException expected) { - assertTrue(expected.getMessage().contains( - "The Region template [RegionTemplate] must be 'defined before' the Region [TemplateBasedPartitionRegion] referring to the template!")); + + assertThat(expected) + .hasMessageContaining("The Region template [RegionTemplate] must be defined before the Region [TemplateBasedPartitionRegion] referring to the template"); + assertThat(expected).hasNoCause(); + throw expected; } } - } diff --git a/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java b/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java index d2d2bb4a..17118cb4 100644 --- a/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java +++ b/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java @@ -31,10 +31,11 @@ import org.springframework.data.gemfire.test.support.FileSystemUtils; import org.springframework.data.gemfire.test.support.ThreadUtils; /** - * The LocatorProcess class is a main Java class that is used fork and launch a GemFire Locator process using the - * LocatorLauncher class. + * The {@link LocatorProcess} class is a main Java class that is used fork and launch a {@link Locator} process + * using the {@link LocatorLauncher} class. * * @author John Blum + * @see org.apache.geode.distributed.Locator * @see org.apache.geode.distributed.LocatorLauncher * @since 1.5.0 */ @@ -43,11 +44,12 @@ public class LocatorProcess { private static final int DEFAULT_LOCATOR_PORT = 20668; private static final String GEMFIRE_NAME = "SpringDataGemFireLocator"; - private static final String GEMFIRE_LOG_LEVEL = "warning"; + private static final String GEMFIRE_LOG_LEVEL = "error"; private static final String HOSTNAME_FOR_CLIENTS = "localhost"; private static final String HTTP_SERVICE_PORT = "0"; - public static void main(final String... args) throws IOException { + public static void main(String... args) throws IOException { + //runLocator(); runInternalLocator(); @@ -67,8 +69,9 @@ public class LocatorProcess { @SuppressWarnings("unused") private static InternalLocator runInternalLocator() throws IOException { - String hostnameForClients = System.getProperty("spring.gemfire.hostname-for-clients", - HOSTNAME_FOR_CLIENTS); + + String hostnameForClients = + System.getProperty("spring.data.gemfire.locator.hostname-for-clients", HOSTNAME_FOR_CLIENTS); int locatorPort = Integer.getInteger("spring.data.gemfire.locator.port", DEFAULT_LOCATOR_PORT); @@ -90,21 +93,23 @@ public class LocatorProcess { distributedSystemProperties.setProperty(DistributionConfig.LOG_LEVEL_NAME, System.getProperty("spring.data.gemfire.log-level", GEMFIRE_LOG_LEVEL)); - return InternalLocator.startLocator(locatorPort, null, null, null, null, - true, distributedSystemProperties, hostnameForClients); + return InternalLocator.startLocator(locatorPort, null, null, null, + null, true, distributedSystemProperties, hostnameForClients); } @SuppressWarnings("unused") private static LocatorLauncher runLocator() { + LocatorLauncher locatorLauncher = buildLocatorLauncher(); - // start the GemFire Locator process... + // Start a Pivotal GemFire Locator process... locatorLauncher.start(); return locatorLauncher; } private static LocatorLauncher buildLocatorLauncher() { + return new LocatorLauncher.Builder() .setMemberName(GEMFIRE_NAME) .setHostnameForClients(getProperty("spring.data.gemfire.hostname-for-clients", HOSTNAME_FOR_CLIENTS)) @@ -136,7 +141,9 @@ public class LocatorProcess { } private static void registerShutdownHook() { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + Locator locator = GemfireUtils.getLocator(); if (locator != null) { @@ -146,6 +153,7 @@ public class LocatorProcess { } private static void waitForLocatorStart(final long milliseconds) { + InternalLocator locator = InternalLocator.getLocator(); if (isClusterConfigurationEnabled(locator)) { @@ -158,7 +166,8 @@ public class LocatorProcess { } private static boolean isClusterConfigurationEnabled(final InternalLocator locator) { - return (locator != null && Boolean.valueOf(locator.getDistributedSystem().getProperties().getProperty( - DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME))); + + return locator != null && Boolean.valueOf(locator.getDistributedSystem().getProperties() + .getProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME)); } } diff --git a/src/test/java/org/springframework/data/gemfire/function/ExceptionThrowingFunctionExecutionIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/function/ExceptionThrowingFunctionExecutionIntegrationTest.java index 9a6b0e7b..62614afc 100644 --- a/src/test/java/org/springframework/data/gemfire/function/ExceptionThrowingFunctionExecutionIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/function/ExceptionThrowingFunctionExecutionIntegrationTest.java @@ -42,7 +42,7 @@ import org.springframework.data.gemfire.process.ProcessWrapper; import org.springframework.data.gemfire.test.support.FileSystemUtils; import org.springframework.data.gemfire.test.support.ThreadUtils; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.Assert; /** @@ -63,34 +63,37 @@ import org.springframework.util.Assert; * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner * @since 1.7.0 */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration @SuppressWarnings("unused") public class ExceptionThrowingFunctionExecutionIntegrationTest { - private static ProcessWrapper serverProcess; + private static ProcessWrapper gemfireServer; @Rule - public ExpectedException expectedException = ExpectedException.none(); + public ExpectedException exception = ExpectedException.none(); @Autowired private ExceptionThrowingFunctionExecution exceptionThrowingFunctionExecution; @BeforeClass - public static void setup() throws IOException { + public static void startGemFireServer() throws IOException { + String serverName = ExceptionThrowingFunctionExecutionIntegrationTest.class.getSimpleName().concat("Server"); File serverWorkingDirectory = new File(FileSystemUtils.WORKING_DIRECTORY, serverName.toLowerCase()); - Assert.isTrue(serverWorkingDirectory.isDirectory() || serverWorkingDirectory.mkdirs()); + Assert.isTrue(serverWorkingDirectory.isDirectory() || serverWorkingDirectory.mkdirs(), + String.format("Failed to create working directory [%s]", serverWorkingDirectory)); List arguments = new ArrayList(); arguments.add("-Dgemfire.name=" + serverName); + arguments.add("-Dgemfire.log-level=error"); arguments.add(ExceptionThrowingFunctionExecutionIntegrationTest.class.getName().replace(".", "/") .concat("-server-context.xml")); - serverProcess = ProcessExecutor.launch(serverWorkingDirectory, ServerProcess.class, + gemfireServer = ProcessExecutor.launch(serverWorkingDirectory, ServerProcess.class, arguments.toArray(new String[arguments.size()])); waitForServerStart(TimeUnit.SECONDS.toMillis(20)); @@ -99,34 +102,41 @@ public class ExceptionThrowingFunctionExecutionIntegrationTest { } private static void waitForServerStart(final long milliseconds) { + ThreadUtils.timedWait(milliseconds, TimeUnit.MILLISECONDS.toMillis(500), new ThreadUtils.WaitCondition() { - private File serverPidControlFile = new File(serverProcess.getWorkingDirectory(), + + private File serverPidControlFile = new File(gemfireServer.getWorkingDirectory(), ServerProcess.getServerProcessControlFilename()); - @Override public boolean waiting() { + @Override + public boolean waiting() { return !serverPidControlFile.isFile(); } }); } @AfterClass - public static void tearDown() { - serverProcess.shutdown(); + public static void stopGemFireServer() { + + gemfireServer.shutdown(); if (Boolean.valueOf(System.getProperty("spring.gemfire.fork.clean", Boolean.TRUE.toString()))) { - org.springframework.util.FileSystemUtils.deleteRecursively(serverProcess.getWorkingDirectory()); + org.springframework.util.FileSystemUtils.deleteRecursively(gemfireServer.getWorkingDirectory()); } } @Test public void exceptionThrowingFunctionExecutionRethrowsException() { - expectedException.expect(FunctionException.class); - expectedException.expectCause(isA(IllegalArgumentException.class)); - expectedException.expectMessage(containsString("Execution of Function with ID 'exceptionThrowingFunction' failed")); + + exception.expect(FunctionException.class); + exception.expectCause(isA(IllegalArgumentException.class)); + exception.expectMessage(containsString("Execution of Function with ID [exceptionThrowingFunction] failed")); + exceptionThrowingFunctionExecution.exceptionThrowingFunction(); } public static class ExceptionThrowingFunction extends FunctionAdapter { + @Override public String getId() { return "exceptionThrowingFunction"; @@ -136,5 +146,4 @@ public class ExceptionThrowingFunctionExecutionIntegrationTest { context.getResultSender().sendException(new IllegalArgumentException("TEST")); } } - } diff --git a/src/test/java/org/springframework/data/gemfire/function/execution/AbstractFunctionExecutionTest.java b/src/test/java/org/springframework/data/gemfire/function/execution/AbstractFunctionExecutionTest.java index e7e662eb..d73194fe 100644 --- a/src/test/java/org/springframework/data/gemfire/function/execution/AbstractFunctionExecutionTest.java +++ b/src/test/java/org/springframework/data/gemfire/function/execution/AbstractFunctionExecutionTest.java @@ -66,18 +66,21 @@ public class AbstractFunctionExecutionTest { @Mock private Execution mockExecution; - // TODO add more tests!!! + // TODO: add more tests!!! @Test @SuppressWarnings("unchecked") public void executeWithResults() throws Exception { + Object[] args = { "one", "two", "three" }; + List results = Arrays.asList(args); Function mockFunction = mock(Function.class, "MockFunction"); + ResultCollector mockResultCollector = mock(ResultCollector.class, "MockResultCollector"); - when(mockExecution.withArgs(eq(args))).thenReturn(mockExecution); + when(mockExecution.setArguments(eq(args))).thenReturn(mockExecution); when(mockExecution.execute(eq(mockFunction))).thenReturn(mockResultCollector); when(mockFunction.hasResult()).thenReturn(true); when(mockResultCollector.getResult(500, TimeUnit.MILLISECONDS)).thenReturn(results); @@ -94,7 +97,7 @@ public class AbstractFunctionExecutionTest { assertThat(actualResults).isNotNull(); assertThat(actualResults).isEqualTo((Iterable) results); - verify(mockExecution, times(1)).withArgs(eq(args)); + verify(mockExecution, times(1)).setArguments(eq(args)); verify(mockExecution, never()).withCollector(any(ResultCollector.class)); verify(mockExecution, never()).withFilter(any(Set.class)); verify(mockExecution, times(1)).execute(eq(mockFunction)); @@ -173,8 +176,11 @@ public class AbstractFunctionExecutionTest { @Test public void executeAndExtractWithThrowsException() { + AbstractFunctionExecution functionExecution = new AbstractFunctionExecution() { - @Override protected Execution getExecution() { + + @Override + protected Execution getExecution() { return mockExecution; } @@ -186,7 +192,7 @@ public class AbstractFunctionExecutionTest { expectedException.expect(FunctionException.class); expectedException.expectCause(isA(IllegalArgumentException.class)); - expectedException.expectMessage(containsString("Execution of Function with ID 'TestFunction' failed")); + expectedException.expectMessage(containsString("Execution of Function with ID [TestFunction] failed")); functionExecution.setFunctionId("TestFunction").executeAndExtract(); } diff --git a/src/test/java/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests.java index 5b99423c..d302433f 100644 --- a/src/test/java/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests.java @@ -45,6 +45,9 @@ public class RepositoryClientRegionIntegrationTests extends ClientServerIntegrat @BeforeClass public static void startGemFireServer() throws Exception { + + System.setProperty("gemfire.log-level", GEMFIRE_LOG_LEVEL); + int availablePort = findAvailablePort(); gemfireServer = run(ServerProcess.class, @@ -58,6 +61,7 @@ public class RepositoryClientRegionIntegrationTests extends ClientServerIntegrat @AfterClass public static void stopGemFireServer() { + System.clearProperty("gemfire.log-level"); System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY); stop(gemfireServer); } 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 c2472602..bc7d6eb3 100644 --- a/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java +++ b/src/test/java/org/springframework/data/gemfire/test/MockCacheFactoryBean.java @@ -19,8 +19,11 @@ import org.apache.geode.cache.GemFireCache; import org.springframework.data.gemfire.CacheFactoryBean; /** + * Mock {@link CacheFactoryBean} used in Unit Tests. + * * @author David Turanski * @author John Blum + * @see org.springframework.data.gemfire.CacheFactoryBean */ public class MockCacheFactoryBean extends CacheFactoryBean { @@ -57,6 +60,7 @@ public class MockCacheFactoryBean extends CacheFactoryBean { setTransactionListeners(it.getTransactionListeners()); setTransactionWriter(it.getTransactionWriter()); setUseBeanFactoryLocator(it.isUseBeanFactoryLocator()); + setUseClusterConfiguration(it.getUseClusterConfiguration()); }); applyPeerCacheConfigurers(cacheFactoryBean.getCompositePeerCacheConfigurer()); diff --git a/src/test/java/org/springframework/data/gemfire/test/support/ClientServerIntegrationTestsSupport.java b/src/test/java/org/springframework/data/gemfire/test/support/ClientServerIntegrationTestsSupport.java index 70d08db5..4ec1dd52 100644 --- a/src/test/java/org/springframework/data/gemfire/test/support/ClientServerIntegrationTestsSupport.java +++ b/src/test/java/org/springframework/data/gemfire/test/support/ClientServerIntegrationTestsSupport.java @@ -190,7 +190,7 @@ public class ClientServerIntegrationTestsSupport { /* (non-Javadoc) */ protected static ProcessWrapper run(File workingDirectory, Class type, String... arguments) throws IOException { - return (isProcessRunAuto() ? launch(createDirectory(workingDirectory), type, arguments) : null); + return isProcessRunAuto() ? launch(createDirectory(workingDirectory), type, arguments) : null; } /* (non-Javadoc) */ @@ -202,7 +202,7 @@ public class ClientServerIntegrationTestsSupport { protected static ProcessWrapper run(File workingDirectory, String classpath, Class type, String... arguments) throws IOException { - return (isProcessRunAuto() ? launch(createDirectory(workingDirectory), classpath, type, arguments) : null); + return isProcessRunAuto() ? launch(createDirectory(workingDirectory), classpath, type, arguments) : null; } /* (non-Javadoc) */ diff --git a/src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java b/src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java index 364e4cb7..7b6639d7 100644 --- a/src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java +++ b/src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java @@ -73,6 +73,7 @@ public abstract class ThreadUtils { } // TODO rename interface to Condition and waiting() method to evaluate() + @FunctionalInterface public interface WaitCondition { boolean waiting(); } diff --git a/src/test/java/org/springframework/data/gemfire/util/RegionUtilsUnitTests.java b/src/test/java/org/springframework/data/gemfire/util/RegionUtilsUnitTests.java new file mode 100644 index 00000000..272a0928 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/util/RegionUtilsUnitTests.java @@ -0,0 +1,85 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.util; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.geode.cache.DataPolicy; +import org.junit.Test; + +/** + * Unit tests for {@link RegionUtils}. + * + * @author John Blum + * @see org.springframework.data.gemfire.util.RegionUtils + * @since 2.1.0 + */ +public class RegionUtilsUnitTests { + + @Test + public void assertAllDataPoliciesWithNullPersistentPropertyIsCompatible() { + + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(DataPolicy.PARTITION, null); + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(DataPolicy.REPLICATE, null); + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(DataPolicy.PERSISTENT_PARTITION, null); + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(DataPolicy.PERSISTENT_REPLICATE, null); + } + + @Test + public void assertNonPersistentDataPolicyWithNoPersistenceIsCompatible() { + + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(DataPolicy.PARTITION, false); + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(DataPolicy.REPLICATE, false); + } + + @Test + public void assertPersistentDataPolicyWithPersistenceIsCompatible() { + + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(DataPolicy.PERSISTENT_PARTITION, true); + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(DataPolicy.PERSISTENT_REPLICATE, true); + } + + @Test(expected = IllegalArgumentException.class) + public void testAssertNonPersistentDataPolicyWithPersistentAttribute() { + + try { + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(DataPolicy.REPLICATE, true); + } + catch (IllegalArgumentException expected) { + + assertThat(expected).hasMessage("Data Policy [REPLICATE] is not valid when persistent is true"); + assertThat(expected).hasNoCause(); + + throw expected; + } + } + + @Test(expected = IllegalArgumentException.class) + public void testAssertPersistentDataPolicyWithNonPersistentAttribute() { + + try { + RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(DataPolicy.PERSISTENT_PARTITION, false); + } + catch (IllegalArgumentException expected) { + + assertThat(expected).hasMessage("Data Policy [PERSISTENT_PARTITION] is not valid when persistent is false"); + assertThat(expected).hasNoCause(); + + throw expected; + } + } +} diff --git a/src/test/resources/cluster_config.zip b/src/test/resources/cluster_config.zip index 8d334323..a0d4ebc5 100644 Binary files a/src/test/resources/cluster_config.zip and b/src/test/resources/cluster_config.zip differ diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml index 63ea4f79..098263de 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -1,6 +1,8 @@ + + %d %5p %40.40c:%4L - %m%n diff --git a/src/test/resources/clusterconfig-cache.xml b/src/test/resources/non-cluster-config-cache.xml similarity index 74% rename from src/test/resources/clusterconfig-cache.xml rename to src/test/resources/non-cluster-config-cache.xml index 56c87472..f3189fab 100644 --- a/src/test/resources/clusterconfig-cache.xml +++ b/src/test/resources/non-cluster-config-cache.xml @@ -1,7 +1,9 @@ - - - + + + java.lang.Integer @@ -20,4 +22,5 @@ java.lang.String + diff --git a/src/test/resources/org/springframework/data/gemfire/cacheUsingClusterConfigurationIntegrationTest.xml b/src/test/resources/org/springframework/data/gemfire/cacheUsingClusterConfigurationIntegrationTest.xml index 247b18bb..37236a01 100644 --- a/src/test/resources/org/springframework/data/gemfire/cacheUsingClusterConfigurationIntegrationTest.xml +++ b/src/test/resources/org/springframework/data/gemfire/cacheUsingClusterConfigurationIntegrationTest.xml @@ -1,22 +1,26 @@ + + CacheUsingSharedConfigurationIntegrationTest 0 - warning - localhost[20668] + error + localhost[${spring.data.gemfire.locator.port:20668}] - diff --git a/src/test/resources/org/springframework/data/gemfire/cacheUsingLocalOnlyConfigurationIntegrationTest.xml b/src/test/resources/org/springframework/data/gemfire/cacheUsingLocalConfigurationIntegrationTest.xml similarity index 68% rename from src/test/resources/org/springframework/data/gemfire/cacheUsingLocalOnlyConfigurationIntegrationTest.xml rename to src/test/resources/org/springframework/data/gemfire/cacheUsingLocalConfigurationIntegrationTest.xml index 35ce66b4..44827412 100644 --- a/src/test/resources/org/springframework/data/gemfire/cacheUsingLocalOnlyConfigurationIntegrationTest.xml +++ b/src/test/resources/org/springframework/data/gemfire/cacheUsingLocalConfigurationIntegrationTest.xml @@ -1,22 +1,25 @@ + + CacheNotUsingSharedConfigurationIntegrationTest - 0 - warning - localhost[20668] + error + localhost[${spring.data.gemfire.locator.port:20668}] - diff --git a/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest-context.xml b/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest-context.xml index 7d13f819..4ee4bf46 100644 --- a/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest-context.xml @@ -1,27 +1,21 @@ - - localhost - 42084 - - - + - + diff --git a/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest-server-context.xml b/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest-server-context.xml index bef4abd0..3c4fe7e7 100644 --- a/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest-server-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTest-server-context.xml @@ -1,32 +1,20 @@ - - localhost - 42084 - + - + - - GemFireDataSourceIntegrationTestServer - 0 - warning - - - - - diff --git a/src/test/resources/org/springframework/data/gemfire/config/xml/cache-ns.xml b/src/test/resources/org/springframework/data/gemfire/config/xml/cache-ns.xml index 18ae4e76..da55e99b 100644 --- a/src/test/resources/org/springframework/data/gemfire/config/xml/cache-ns.xml +++ b/src/test/resources/org/springframework/data/gemfire/config/xml/cache-ns.xml @@ -4,8 +4,8 @@ xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" - http://www.springframework.org/schema/geode http://www.springframework.org/schema/geode/spring-geode.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/geode http://www.springframework.org/schema/geode/spring-geode.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd" default-lazy-init="true"> @@ -13,7 +13,7 @@ default-lazy-init="true"> false - warning + error @@ -33,12 +33,16 @@ default-lazy-init="true"> + + + + + + - - diff --git a/src/test/resources/org/springframework/data/gemfire/config/xml/client-ns.xml b/src/test/resources/org/springframework/data/gemfire/config/xml/client-ns.xml index 82a3c4c8..dfe72ada 100644 --- a/src/test/resources/org/springframework/data/gemfire/config/xml/client-ns.xml +++ b/src/test/resources/org/springframework/data/gemfire/config/xml/client-ns.xml @@ -23,11 +23,9 @@ - - warning - + - + @@ -81,9 +79,7 @@ shortcut="CACHING_PROXY" value-constraint="java.lang.String"/> - - - + @@ -95,7 +91,6 @@ result-policy="${client.regex.interests.result-policy}"/> - diff --git a/src/test/resources/org/springframework/data/gemfire/config/xml/replicated-ns.xml b/src/test/resources/org/springframework/data/gemfire/config/xml/replicated-ns.xml index 351ea23d..39027033 100644 --- a/src/test/resources/org/springframework/data/gemfire/config/xml/replicated-ns.xml +++ b/src/test/resources/org/springframework/data/gemfire/config/xml/replicated-ns.xml @@ -15,7 +15,7 @@ ReplicatedNamespaceConfig 0 - warning + error 64m diff --git a/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests-server-context.xml b/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests-server-context.xml index d7206f08..406fa622 100644 --- a/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests-server-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests-server-context.xml @@ -15,8 +15,7 @@ RepositoryClientRegionIntegrationTestsServer - 0 - warning + error