SGF-738 - Avoid Pool Already Exists Exception on Spring container initialization.

This commit is contained in:
John Blum
2018-04-14 13:17:18 -07:00
parent 75c81c4fa7
commit b13dcffe80
97 changed files with 2999 additions and 2934 deletions

View File

@@ -351,17 +351,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...
@@ -384,9 +384,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 { .. }
----

View File

@@ -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<GemFireCache>
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<GemFireCache>
private Integer messageSyncInterval;
private Integer searchTimeout;
private List<PeerCacheConfigurer> peerCacheConfigurers = Collections.emptyList();
private List<PeerCacheConfigurer> peerCacheConfigurers = new ArrayList<>();
private List<JndiDataSource> jndiDataSources;
@@ -165,13 +166,65 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
*
* @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<PeerCacheConfigurer> peerCacheConfigurers) {
stream(nullSafeIterable(peerCacheConfigurers).spliterator(), false)
.forEach(clientCacheConfigurer -> clientCacheConfigurer.configure(getBeanName(), this));
}
/**
@@ -184,64 +237,13 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
* @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<PeerCacheConfigurer> 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<GemFireCache>
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.<GemFireCache>ofNullable(this.getCache()).ifPresent(cache -> {
Optional.<GemFireCache>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]"),
@@ -278,8 +281,8 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
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);
@@ -297,19 +300,24 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
* @see #fetchCache()
* @see #resolveProperties()
* @see #createFactory(java.util.Properties)
* @see #prepareFactory(Object)
* @see #configureFactory(Object)
* @see #createCache(Object)
*/
@SuppressWarnings("unchecked")
protected <T extends GemFireCache> 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())))));
}
}
@@ -352,7 +360,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
/**
* 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
@@ -365,11 +373,12 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
}
/**
* 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
@@ -382,16 +391,17 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
}
/**
* 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);
}
/**
@@ -401,7 +411,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
* @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);
@@ -418,17 +428,28 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
}
/**
* Creates a new {@link Cache} instance using the provided factory.
* Post processes the {@link CacheFactory} used to create the {@link Cache}.
*
* @param <T> 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 <T> {@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 extends GemFireCache> T createCache(Object factory) {
return (T) Optional.ofNullable(getCache()).orElseGet(((CacheFactory) factory)::create);
return (T) ((CacheFactory) factory).create();
}
/**
@@ -449,16 +470,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
@SuppressWarnings("all")
protected <T extends GemFireCache> 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);
@@ -472,20 +484,34 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
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 extends GemFireCache> 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 -> {
@@ -502,10 +528,11 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
cache.getResourceManager().setEvictionHeapPercentage(evictionHeapPercentage);
});
return cache;
}
/* (non-Javadoc) */
private void configureOffHeapPercentages(GemFireCache cache) {
private GemFireCache configureOffHeapPercentages(GemFireCache cache) {
Optional.ofNullable(getCriticalOffHeapPercentage()).ifPresent(criticalOffHeapPercentage -> {
@@ -522,10 +549,11 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
cache.getResourceManager().setEvictionOffHeapPercentage(evictionOffHeapPercentage);
});
return cache;
}
/* (non-Javadoc) */
private void registerJndiDataSources() {
private GemFireCache registerJndiDataSources(GemFireCache cache) {
nullSafeCollection(getJndiDataSources()).forEach(jndiDataSource -> {
@@ -533,41 +561,30 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
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;
}
/**
@@ -584,7 +601,25 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
.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();
}
}
/**
@@ -612,7 +647,9 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
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;
@@ -701,11 +738,12 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
* @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());
}
}
@@ -715,9 +753,11 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
* @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;
@@ -735,7 +775,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
@Override
@SuppressWarnings("all")
public GemFireCache getObject() throws Exception {
return Optional.ofNullable(this.<GemFireCache>getCache()).orElseGet(this::init);
return Optional.<GemFireCache>ofNullable(getCache()).orElseGet(this::init);
}
/**
@@ -751,26 +791,25 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
}
/**
* 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;
}
/**
@@ -807,28 +846,6 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
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.
*
@@ -939,7 +956,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
* or not.
*/
public Boolean getEnableAutoReconnect() {
return enableAutoReconnect;
return this.enableAutoReconnect;
}
/**
@@ -1056,6 +1073,29 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
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.
@@ -1163,7 +1203,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
* @see org.springframework.data.gemfire.config.annotation.PeerCacheConfigurer
*/
public void setPeerCacheConfigurers(List<PeerCacheConfigurer> peerCacheConfigurers) {
this.peerCacheConfigurers = Optional.ofNullable(peerCacheConfigurers).orElseGet(Collections::emptyList);
Optional.ofNullable(peerCacheConfigurers).ifPresent(this.peerCacheConfigurers::addAll);
}
/**
@@ -1278,9 +1318,9 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
* @see org.apache.geode.cache.client.ClientCacheFactory
*/
T initialize(T cacheFactory);
}
/* (non-Javadoc) */
public static class DynamicRegionSupport {
private Boolean persistent = Boolean.TRUE;
@@ -1322,23 +1362,25 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
}
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<ConfigProperty> props;
private List<ConfigProperty> configProperties;
private Map<String, String> attributes;
public Map<String, String> getAttributes() {
return attributes;
return this.attributes;
}
public void setAttributes(Map<String, String> attributes) {
@@ -1346,11 +1388,11 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
}
public List<ConfigProperty> getProps() {
return props;
return this.configProperties;
}
public void setProps(List<ConfigProperty> props) {
this.props = props;
this.configProperties = props;
}
}
}

View File

@@ -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<K, V> extends RegionLookupFactoryBean<K, V> {
private List<RegionConfigurer> 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<RegionConfigurer> 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<RegionConfigurer> regionConfigurers) {
if (this instanceof RegionFactoryBean) {
StreamSupport.stream(nullSafeIterable(regionConfigurers).spliterator(), false)
.forEach(regionConfigurer -> regionConfigurer.configure(regionName, (RegionFactoryBean<K, V>) this));
}
else if (this instanceof ClientRegionFactoryBean) {
StreamSupport.stream(nullSafeIterable(regionConfigurers).spliterator(), false)
.forEach(regionConfigurer -> regionConfigurer.configure(regionName, (ClientRegionFactoryBean<K, V>) this));
}
}
}

View File

@@ -21,8 +21,10 @@ import java.util.concurrent.ConcurrentMap;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.internal.GemFireVersion;
import org.springframework.data.gemfire.config.support.GemfireFeature;
import org.springframework.data.gemfire.util.RegionUtils;
import org.springframework.util.ClassUtils;
import org.w3c.dom.Element;
/**
* {@link GemfireUtils} is an abstract utility class encapsulating common functionality to access features
@@ -37,11 +39,20 @@ import org.springframework.util.ClassUtils;
@SuppressWarnings("unused")
public abstract class GemfireUtils extends RegionUtils {
public final static String APACHE_GEODE_NAME = "Apache Geode";
public final static String APACHE_GEODE_NAME = "Aache Geode";
public final static String GEMFIRE_NAME = apacheGeodeProductName();
public final static String GEMFIRE_VERSION = apacheGeodeVersion();
public final static String UNKNOWN = "unknown";
private static final String ASYNC_EVENT_QUEUE_ELEMENT_NAME = "async-event-queue";
private static final String ASYNC_EVENT_QUEUE_TYPE_NAME = "org.apache.geode.cache.asyncqueue.AsyncEventQueue";
private static final String CQ_ELEMENT_NAME = "cq-listener-container";
private static final String CQ_TYPE_NAME = "org.apache.geode.cache.query.internal.cq.CqServiceFactoryImpl";
private static final String GATEWAY_RECEIVER_ELEMENT_NAME = "gateway-receiver";
private static final String GATEWAY_RECEIVER_TYPE_NAME = "org.apache.geode.internal.cache.wan.GatewayReceiverFactoryImpl";
private static final String GATEWAY_SENDER_ELEMENT_NAME = "gateway-sender";
private static final String GATEWAY_SENDER_TYPE_NAME = "org.apache.geode.internal.cache.wan.GatewaySenderFactoryImpl";
/* (non-Javadoc) */
public static String apacheGeodeProductName() {
@@ -65,52 +76,78 @@ public abstract class GemfireUtils extends RegionUtils {
}
/* (non-Javadoc) */
public static boolean isGemfireVersionGreaterThanEqualTo(double expectedVersion) {
double actualVersion = Double.parseDouble(GEMFIRE_VERSION.substring(0, 3));
return actualVersion >= expectedVersion;
public static boolean isClassAvailable(String fullyQualifiedClassName) {
return ClassUtils.isPresent(fullyQualifiedClassName, GemfireUtils.class.getClassLoader());
}
/* (non-Javadoc) */
public static boolean isGemfireVersion65OrAbove() {
// expected 'major.minor'
try {
double version = Double.parseDouble(GEMFIRE_VERSION.substring(0, 3));
return version >= 6.5;
}
catch (NumberFormatException e) {
// NOTE based on logic from the PartitionedRegionFactoryBean class...
return ConcurrentMap.class.isAssignableFrom(Region.class);
}
public static boolean isGemfireFeatureAvailable(GemfireFeature feature) {
boolean featureAvailable = (!GemfireFeature.AEQ.equals(feature) || isAsyncEventQueueAvailable());
featureAvailable &= (!GemfireFeature.CONTINUOUS_QUERY.equals(feature) || isContinuousQueryAvailable());
featureAvailable &= (!GemfireFeature.WAN.equals(feature) || isGatewayAvailable());
return featureAvailable;
}
/* (non-Javadoc) */
public static boolean isGemfireVersion7OrAbove() {
try {
return isGemfireVersionGreaterThanEqualTo(7.0);
}
catch (NumberFormatException e) {
// NOTE the org.apache.geode.distributed.ServerLauncher class only exists in GemFire v 7.0.x or above...
return ClassUtils.isPresent("org.apache.geode.distributed.ServerLauncher",
Thread.currentThread().getContextClassLoader());
}
public static boolean isGemfireFeatureAvailable(Element element) {
boolean featureAvailable = (!isAsyncEventQueue(element) || isAsyncEventQueueAvailable());
featureAvailable &= (!isContinuousQuery(element) || isContinuousQueryAvailable());
featureAvailable &= (!isGateway(element) || isGatewayAvailable());
return featureAvailable;
}
/* (non-Javadoc) */
public static boolean isGemfireVersion8OrAbove() {
public static boolean isGemfireFeatureUnavailable(GemfireFeature feature) {
return !isGemfireFeatureAvailable(feature);
}
try {
return isGemfireVersionGreaterThanEqualTo(8.0);
}
catch (NumberFormatException e) {
// NOTE the org.apache.geode.management.internal.web.domain.LinkIndex class only exists
// in GemFire v 8.0.0 or above...
return ClassUtils.isPresent("org.apache.geode.management.internal.web.domain.LinkIndex",
Thread.currentThread().getContextClassLoader());
}
/* (non-Javadoc) */
public static boolean isGemfireFeatureUnavailable(Element element) {
return !isGemfireFeatureAvailable(element);
}
/* (non-Javadoc) */
private static boolean isAsyncEventQueue(Element element) {
return ASYNC_EVENT_QUEUE_ELEMENT_NAME.equals(element.getLocalName());
}
/* (non-Javadoc) */
private static boolean isAsyncEventQueueAvailable() {
return isClassAvailable(ASYNC_EVENT_QUEUE_TYPE_NAME);
}
/* (non-Javadoc) */
private static boolean isContinuousQuery(Element element) {
return CQ_ELEMENT_NAME.equals(element.getLocalName());
}
/* (non-Javadoc) */
private static boolean isContinuousQueryAvailable() {
return isClassAvailable(CQ_TYPE_NAME);
}
/* (non-Javadoc) */
private static boolean isGateway(Element element) {
String elementLocalName = element.getLocalName();
return (GATEWAY_RECEIVER_ELEMENT_NAME.equals(elementLocalName)
|| GATEWAY_SENDER_ELEMENT_NAME.equals(elementLocalName));
}
/* (non-Javadoc) */
private static boolean isGatewayAvailable() {
return isClassAvailable(GATEWAY_SENDER_TYPE_NAME);
}
public static void main(final String... args) {
System.out.printf("GemFire Version %1$s%n", GEMFIRE_VERSION);
System.out.printf("GemFire Product Name (%1$s) Version (%2$s)%n", GEMFIRE_NAME, GEMFIRE_VERSION);
//System.out.printf("Is GemFire Version 6.5 of Above? %1$s%n", isGemfireVersion65OrAbove());
//System.out.printf("Is GemFire Version 7.0 of Above? %1$s%n", isGemfireVersion7OrAbove());
}

View File

@@ -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
* &gt;gfe:lookup-region/&lt; 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<K, V> extends RegionLookupFactoryBean<K, V> {
private AsyncEventQueue[] asyncEventQueues;
private Boolean cloningEnabled;
private Boolean enableStatistics;
private AsyncEventQueue[] asyncEventQueues;
private CacheListener<K, V>[] cacheListeners;
private CacheLoader<K, V> cacheLoader;
@@ -66,166 +68,123 @@ public class LookupRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
@Override
public void afterPropertiesSet() throws Exception {
super.afterPropertiesSet();
AttributesMutator<K, V> 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<K, V> 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<K, V>[] cacheListeners) {
this.cacheListeners = cacheListeners;
}
/* (non-Javadoc) */
public void setCacheLoader(CacheLoader<K, V> cacheLoader) {
this.cacheLoader = cacheLoader;
}
/* (non-Javadoc) */
public void setCacheWriter(CacheWriter<K, V> cacheWriter) {
this.cacheWriter = cacheWriter;
}
/* (non-Javadoc) */
public void setCloningEnabled(Boolean cloningEnabled) {
this.cloningEnabled = cloningEnabled;
}
/* (non-Javadoc) */
public void setCustomEntryIdleTimeout(CustomExpiry<K, V> customEntryIdleTimeout) {
setStatisticsEnabled(customEntryIdleTimeout != null);
this.customEntryIdleTimeout = customEntryIdleTimeout;
}
/* (non-Javadoc) */
public void setCustomEntryTimeToLive(CustomExpiry<K, V> 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()));
}
}

View File

@@ -15,9 +15,9 @@
*/
package org.springframework.data.gemfire;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.RegionFactory;
import org.springframework.data.gemfire.util.RegionUtils;
import org.springframework.util.Assert;
/**
@@ -29,11 +29,6 @@ public class PartitionedRegionFactoryBean<K, V> extends RegionFactoryBean<K, V>
@Override
protected void resolveDataPolicy(RegionFactory<K, V> regionFactory, Boolean persistent, DataPolicy dataPolicy) {
// First, verify the GemFire version is 6.5 or Higher when Persistence is specified...
Assert.isTrue(!DataPolicy.PERSISTENT_PARTITION.equals(dataPolicy) || GemfireUtils.isGemfireVersion65OrAbove(),
String.format("Persistent PARTITION Regions can only be used from GemFire 6.5 onwards; current version is [%s].",
CacheFactory.getVersion()));
if (dataPolicy == null) {
dataPolicy = (isPersistent() ? DataPolicy.PERSISTENT_PARTITION : DataPolicy.PARTITION);
}
@@ -45,7 +40,7 @@ public class PartitionedRegionFactoryBean<K, V> extends RegionFactoryBean<K, V>
}
// Validate the data-policy and persistent attributes are compatible when specified!
assertDataPolicyAndPersistentAttributesAreCompatible(dataPolicy);
RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(dataPolicy, persistent);
regionFactory.setDataPolicy(dataPolicy);
setDataPolicy(dataPolicy);

View File

@@ -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<K, V> extends RegionLookupFactoryBean<K, V>
// TODO: Rename to PeerRegionFatoryBean in SD Lovelace
public abstract class RegionFactoryBean<K, V> extends ConfigurableRegionFactoryBean<K, V>
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<K, V> extends RegionLookupFactoryBean<K,
private GatewaySender[] gatewaySenders;
private List<RegionConfigurer> regionConfigurers = Collections.emptyList();
private RegionAttributes<K, V> 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<K, V> extends RegionLookupFactoryBean<K,
return enableAsLockGrantor(region);
}
/* (non-Javadoc) */
private void applyRegionConfigurers(String regionName) {
applyRegionConfigurers(regionName, getCompositeRegionConfigurer());
}
/**
* Null-safe operation to apply the given array of {@link RegionConfigurer RegionConfigurers}
* to this {@link RegionFactoryBean}.
*
* @param regionName {@link String} containing the name of the {@link Region}.
* @param regionConfigurers array of {@link RegionConfigurer RegionConfigurers} applied
* to this {@link RegionFactoryBean}.
* @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 RegionFactoryBean}.
*
* @param regionName {@link String} containing the name of the {@link Region}.
* @param regionConfigurers {@link Iterable} of {@link RegionConfigurer RegionConfigurers} applied
* to this {@link RegionFactoryBean}.
* @see org.springframework.data.gemfire.config.annotation.RegionConfigurer
*/
protected void applyRegionConfigurers(String regionName, Iterable<RegionConfigurer> regionConfigurers) {
StreamSupport.stream(nullSafeIterable(regionConfigurers).spliterator(), false)
.forEach(regionConfigurer -> regionConfigurer.configure(regionName, this));
}
/* (non-Javadoc) */
private Region<K, V> enableAsLockGrantor(Region<K, V> region) {
Optional.ofNullable(region)
@@ -213,7 +159,6 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
return region;
}
/* (non-Javadoc) */
private Region<K, V> newRegion(RegionFactory<K, V> regionFactory, Region<?, ?> parentRegion, String regionName) {
return Optional.ofNullable(parentRegion)
@@ -230,7 +175,6 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
});
}
/* (non-Javadoc) */
private Cache resolveCache(GemFireCache gemfireCache) {
return Optional.ofNullable(gemfireCache)
@@ -239,7 +183,6 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
.orElseThrow(() -> newIllegalArgumentException("Peer Cache is required"));
}
/* (non-Javadoc) */
private RegionAttributes<K, V> verifyLockGrantorEligibility(RegionAttributes<K, V> regionAttributes, Scope scope) {
Optional.ofNullable(regionAttributes).ifPresent(attributes ->
@@ -249,9 +192,8 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
return regionAttributes;
}
/* (non-Javadoc) */
private boolean verifyScope(Scope scope) {
return (scope == null || Scope.GLOBAL.equals(scope));
return scope == null || Scope.GLOBAL.equals(scope);
}
/**
@@ -314,7 +256,7 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
Optional.ofNullable(this.evictionAttributes).ifPresent(regionFactory::setEvictionAttributes);
stream(nullSafeArray(this.gatewaySenders, GatewaySender.class))
.forEach(gatewaySender -> 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<K, V> extends RegionLookupFactoryBean<K,
return regionFactory;
}
/**
* Returns a reference to the Composite {@link RegionConfigurer} used to apply additional configuration
* to this {@link RegionFactoryBean} on Spring container initialization.
*
* @return the Composite {@link RegionConfigurer}.
* @see org.springframework.data.gemfire.config.annotation.RegionConfigurer
*/
protected RegionConfigurer getCompositeRegionConfigurer() {
return this.compositeRegionConfigurer;
}
/*
* (non-Javadoc)
*
* This method is not considered part of the RegionFactoryBean API and is strictly used for testing purposes!
*
* NOTE cannot pass RegionAttributes.class as the "targetType" in the second invocation of getFieldValue(..)
* NOTE: Cannot pass RegionAttributes.class as the "targetType" in the second invocation of getFieldValue(..)
* since the "regionAttributes" field is naively declared as a instance of the implementation class type
* (RegionAttributesImpl) rather than the interface type (RegionAttributes)...
* so much for 'programming to interfaces' in GemFire!
@@ -378,7 +309,6 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
.orElseGet(() -> RegionShortcutToDataPolicyConverter.INSTANCE.convert(regionShortcut));
}
/* (non-Javadoc) */
@SuppressWarnings("unchecked")
private <T> Optional<T> getFieldValue(Object source, String fieldName, Class<T> targetType) {
@@ -470,27 +400,30 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
// NOTE: PartitionAttributes are created by certain RegionShortcuts; need the null check since RegionAttributes
// can technically return null!
// NOTE: most likely, the PartitionAttributes will never be null since the PartitionRegionFactoryBean always
// NOTE: Most likely, the PartitionAttributes will never be null since the PartitionRegionFactoryBean always
// sets a PartitionAttributesFactoryBean BeanBuilder on the RegionAttributesFactoryBean "partitionAttributes"
// property.
if (regionAttributes.getPartitionAttributes() != null) {
PartitionAttributes partitionAttributes = regionAttributes.getPartitionAttributes();
PartitionAttributesFactory partitionAttributesFactory = new PartitionAttributesFactory(partitionAttributes);
RegionShortcutWrapper shortcutWrapper = RegionShortcutWrapper.valueOf(shortcut);
// NOTE however, since the default value of redundancy is 0, we need to account for 'redundant'
// NOTE: However, since the default value of redundancy is 0, we need to account for 'redundant'
// RegionShortcut types, which specify a redundancy of 1.
if (shortcutWrapper.isRedundant() && partitionAttributes.getRedundantCopies() == 0) {
partitionAttributesFactory.setRedundantCopies(1);
}
// NOTE and, since the default value of localMaxMemory is based on the system memory, we need to account for
// 'proxy' RegionShortcut types, which specify a local max memory of 0.
// NOTE: And, since the default value of localMaxMemory is based on the system memory, we need to
// account for 'proxy' RegionShortcut types, which specify a local max memory of 0.
if (shortcutWrapper.isProxy()) {
partitionAttributesFactory.setLocalMaxMemory(0);
}
// NOTE internally, RegionFactory.setPartitionAttributes handles merging the PartitionAttributes, hooray!
// NOTE: Internally, RegionFactory.setPartitionAttributes handles merging the PartitionAttributes, hooray!
regionFactory.setPartitionAttributes(partitionAttributesFactory.create());
}
}
@@ -521,12 +454,12 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
&& ((UserSpecifiedRegionAttributes) regionAttributes).hasEvictionAttributes());
}
/* (non-Javadoc) */
private boolean isDiskStoreConfigurationAllowed() {
boolean allow = StringUtils.hasText(this.diskStoreName);
allow &= (getDataPolicy().withPersistence() || (getAttributes() != null
allow &= (getDataPolicy().withPersistence()
|| (getAttributes() != null
&& getAttributes().getEvictionAttributes() != null
&& EvictionAction.OVERFLOW_TO_DISK.equals(attributes.getEvictionAttributes().getAction())));
@@ -541,23 +474,11 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
* @return true when the user specified an explicit value for the persistent attribute and it is true;
* false otherwise.
* @see #isNotPersistent()
* @see #isPersistentUnspecified()
*/
protected boolean isPersistent() {
return Boolean.TRUE.equals(persistent);
}
/**
* Determines whether the user explicitly set the 'persistent' attribute or not.
*
* @return a boolean value indicating whether the user explicitly set the 'persistent' attribute to true or false.
* @see #isPersistent()
* @see #isNotPersistent()
*/
protected boolean isPersistentUnspecified() {
return (persistent == null);
}
/**
* Returns true when the user explicitly specified a value for the persistent attribute and it is false. If the
* persistent attribute was not explicitly specified, then the persistence setting is implicitly undefined
@@ -566,38 +487,16 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
* @return true when the user specified an explicit value for the persistent attribute and it is false;
* false otherwise.
* @see #isPersistent()
* @see #isPersistentUnspecified()
*/
protected boolean isNotPersistent() {
return Boolean.FALSE.equals(persistent);
}
/**
* Validates that the settings for Data Policy and the 'persistent' attribute in &lt;gfe:*-region&gt; elements
* are compatible.
*
* @param resolvedDataPolicy the GemFire Data Policy resolved form the Spring GemFire XML namespace configuration
* meta-data.
* @see #isPersistent()
* @see #isNotPersistent()
* @see org.apache.geode.cache.DataPolicy
*/
protected void assertDataPolicyAndPersistentAttributesAreCompatible(DataPolicy resolvedDataPolicy) {
if (resolvedDataPolicy.withPersistence()) {
Assert.isTrue(isPersistentUnspecified() || isPersistent(), String.format(
"Data Policy [%s] is invalid when persistent is false.", resolvedDataPolicy));
}
else {
// NOTE otherwise, the Data Policy is not persistent, so...
Assert.isTrue(isPersistentUnspecified() || isNotPersistent(), String.format(
"Data Policy [%s] is invalid when persistent is true.", resolvedDataPolicy));
}
}
/**
=======
>>>>>>> c22ebe6... DATAGEODE-12 - Introduce Spring Configurers to flexibly alter Spring Data GemFire configuration when using Annotation config.
=======
>>>>>>> 1fd41c9... DATAGEODE-100 - Avoid Pool Already Exists Exception on Spring container initialization.
* Validates and sets the Data Policy on the RegionFactory used to create and configure the Region from this
* FactoryBean.
*
@@ -612,7 +511,7 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
protected void resolveDataPolicy(RegionFactory<K, V> regionFactory, Boolean persistent, DataPolicy dataPolicy) {
if (dataPolicy != null) {
assertDataPolicyAndPersistentAttributesAreCompatible(dataPolicy);
RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(dataPolicy, this.persistent);
regionFactory.setDataPolicy(dataPolicy);
setDataPolicy(dataPolicy);
}
@@ -637,8 +536,9 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
DataPolicy resolvedDataPolicy = new DataPolicyConverter().convert(dataPolicy);
Assert.notNull(resolvedDataPolicy, String.format("Data Policy [%s] is invalid.", dataPolicy));
assertDataPolicyAndPersistentAttributesAreCompatible(resolvedDataPolicy);
Assert.notNull(resolvedDataPolicy, String.format("Data Policy [%s] is invalid", dataPolicy));
RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(resolvedDataPolicy, this.persistent);
regionFactory.setDataPolicy(resolvedDataPolicy);
setDataPolicy(resolvedDataPolicy);
@@ -646,17 +546,17 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
else {
DataPolicy regionAttributesDataPolicy = getDataPolicy(getAttributes(), DataPolicy.DEFAULT);
DataPolicy resolvedDataPolicy = (isPersistent() && DataPolicy.DEFAULT.equals(regionAttributesDataPolicy)
? DataPolicy.PERSISTENT_REPLICATE : regionAttributesDataPolicy);
assertDataPolicyAndPersistentAttributesAreCompatible(resolvedDataPolicy);
DataPolicy resolvedDataPolicy = isPersistent() && DataPolicy.DEFAULT.equals(regionAttributesDataPolicy)
? DataPolicy.PERSISTENT_REPLICATE : regionAttributesDataPolicy;
RegionUtils.assertDataPolicyAndPersistentAttributeAreCompatible(resolvedDataPolicy, this.persistent);
regionFactory.setDataPolicy(resolvedDataPolicy);
setDataPolicy(resolvedDataPolicy);
}
}
/* (non-Javadoc) */
private DataPolicy getDataPolicy(RegionAttributes regionAttributes, DataPolicy defaultDataPolicy) {
return Optional.ofNullable(regionAttributes).map(RegionAttributes::getDataPolicy).orElse(defaultDataPolicy);
}
@@ -877,31 +777,6 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
this.persistent = persistent;
}
/**
* Null-safe operation to set an array of {@link RegionConfigurer RegionConfigurers} used to apply
* additional configuration to this {@link RegionFactoryBean} when using Annotation-based configuration.
*
* @param regionConfigurers array of {@link RegionConfigurer RegionConfigurers} used to apply
* additional configuration to this {@link RegionFactoryBean}.
* @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 RegionFactoryBean} when using Annotation-based configuration.
*
* @param regionConfigurers {@link Iterable} of {@link RegionConfigurer RegionConfigurers} used to apply
* additional configuration to this {@link RegionFactoryBean}.
* @see org.springframework.data.gemfire.config.annotation.RegionConfigurer
*/
public void setRegionConfigurers(List<RegionConfigurer> regionConfigurers) {
this.regionConfigurers = Optional.ofNullable(regionConfigurers).orElseGet(Collections::emptyList);
}
public Scope getScope() {
return this.scope;
}
@@ -936,16 +811,14 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
this.valueConstraint = valueConstraint;
}
/**
* @inheritDoc
*/
@Override
@SuppressWarnings("all")
public void start() {
if (!ObjectUtils.isEmpty(gatewaySenders)) {
synchronized (gatewaySenders) {
for (GatewaySender gatewaySender: gatewaySenders) {
if (!ObjectUtils.isEmpty(this.gatewaySenders)) {
synchronized (this.gatewaySenders) {
for (Object obj : this.gatewaySenders) {
GatewaySender gatewaySender = (GatewaySender) obj;
if (!(gatewaySender.isManualStart() || gatewaySender.isRunning())) {
gatewaySender.start();
}
@@ -956,24 +829,19 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
this.running = true;
}
/**
* @inheritDoc
*/
@Override
public void stop(Runnable callback) {
stop();
callback.run();
}
/**
* @inheritDoc
*/
@Override
@SuppressWarnings("all")
public void stop() {
if (!ObjectUtils.isEmpty(gatewaySenders)) {
synchronized (gatewaySenders) {
for (GatewaySender gatewaySender : gatewaySenders) {
if (!ObjectUtils.isEmpty(this.gatewaySenders)) {
synchronized (this.gatewaySenders) {
for (GatewaySender gatewaySender : this.gatewaySenders) {
gatewaySender.stop();
}
}
@@ -982,25 +850,16 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
this.running = false;
}
/**
* @inheritDoc
*/
@Override
public boolean isRunning() {
return this.running;
}
/**
* @inheritDoc
*/
@Override
public int getPhase() {
return Integer.MAX_VALUE;
}
/**
* @inheritDoc
*/
@Override
public boolean isAutoStartup() {
return true;

View File

@@ -47,6 +47,7 @@ import org.springframework.util.StringUtils;
* @see org.springframework.data.gemfire.support.AbstractFactoryBeanSupport
*/
@SuppressWarnings("unused")
// TODO: Rename to ResolvableRegionFactoryBean in SD Lovelace
public abstract class RegionLookupFactoryBean<K, V> extends AbstractFactoryBeanSupport<Region<K, V>>
implements InitializingBean {
@@ -74,15 +75,12 @@ public abstract class RegionLookupFactoryBean<K, V> 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.<K, V>getSubregion(regionName))
@@ -101,6 +99,35 @@ public abstract class RegionLookupFactoryBean<K, V> 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<K, V> 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<K, V> 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<K, V> 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;
}

View File

@@ -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<K, V> extends RegionFactoryBean<K, V> {
@Override
protected void resolveDataPolicy(RegionFactory<K, V> regionFactory, Boolean persistent, DataPolicy dataPolicy) {
if (dataPolicy == null) {
dataPolicy = (isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.REPLICATE);
}
@@ -41,7 +43,7 @@ public class ReplicatedRegionFactoryBean<K, V> extends RegionFactoryBean<K, V> {
}
// 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<K, V> extends RegionFactoryBean<K, V> {
@Override
protected void resolveDataPolicy(RegionFactory<K, V> regionFactory, Boolean persistent, String dataPolicy) {
DataPolicy resolvedDataPolicy = null;
if (dataPolicy != null) {
@@ -58,5 +61,4 @@ public class ReplicatedRegionFactoryBean<K, V> extends RegionFactoryBean<K, V> {
resolveDataPolicy(regionFactory, persistent, resolvedDataPolicy);
}
}

View File

@@ -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<InetSocketAddress> 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<InetSocketAddress> 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<String, PoolFactoryBean> 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.<ClientCache>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<ConnectionEndpoint> locators) {
this.locators.add(locators);
}
/* (non-Javadoc) */
public void addServers(ConnectionEndpoint... servers) {
this.servers.add(servers);
}
/* (non-Javadoc) */
public void addServers(Iterable<ConnectionEndpoint> servers) {
this.servers.add(servers);
}
@@ -546,40 +530,30 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
return this.durableClientTimeout;
}
/**
* @inheritDoc
*/
@Override
public final void setEnableAutoReconnect(Boolean enableAutoReconnect) {
throw new UnsupportedOperationException("Auto-reconnect does not apply to clients");
}
/**
* @inheritDoc
*/
@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;
}
/**
@@ -599,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;
}
/**
@@ -612,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<ConnectionEndpoint> 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;
}
/**
@@ -705,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;
}
/**
@@ -756,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;
}
/**
@@ -784,133 +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<ConnectionEndpoint> 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;
}
/**
* @inheritDoc
*/
@Override
public final void setUseClusterConfiguration(Boolean useClusterConfiguration) {
throw new UnsupportedOperationException("Cluster-based Configuration is not applicable for clients");
}
/**
* @inheritDoc
*/
@Override
public final Boolean getUseClusterConfiguration() {
return Boolean.FALSE;

View File

@@ -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<K, V> extends RegionLookupFactoryBean<K, V> implements DisposableBean {
public class ClientRegionFactoryBean<K, V> extends ConfigurableRegionFactoryBean<K, V> 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<K, V> extends RegionLookupFactoryBean<K, V>
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<K, V>[] cacheListeners;
@@ -98,12 +104,25 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
private Compressor compressor;
private CustomExpiry<K, V> customEntryIdleTimeout;
private CustomExpiry<K, V> 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<K>[] interests;
private Float loadFactor;
private List<RegionConfigurer> regionConfigurers = Collections.emptyList();
private RegionAttributes<K, V> attributes;
@@ -126,6 +145,8 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
* @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<K, V> extends RegionLookupFactoryBean<K, V>
ClientRegionFactory<K, V> clientRegionFactory =
postProcess(configure(createClientRegionFactory(clientCache, resolveClientRegionShortcut())));
@SuppressWarnings("all")
Region<K, V> 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<RegionConfigurer> 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 &lt;gfe:*-region&gt; 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 &lt;gfe:*-region&gt; 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<K, V> newRegion(ClientRegionFactory<K, V> 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.<K, V>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.<K, V>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<K, V> extends RegionLookupFactoryBean<K, V>
}
/**
* 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<K, V> extends RegionLookupFactoryBean<K, V>
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<K, V> extends RegionLookupFactoryBean<K, V>
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<K, V> extends RegionLookupFactoryBean<K, V>
* 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<K, V> 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<K, V> configure(ClientRegionFactory<K, V> 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<String> 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<String> configureWithRegionAttributes(ClientRegionFactory<K, V> clientRegionFactory) {
AtomicReference<String> 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<K, V> extends RegionLookupFactoryBean<K, V>
return region;
}
/* (non-Javadoc) */
@SuppressWarnings("unchecked")
private Region<K, V> registerInterests(Region<K, V> region) {
@@ -459,6 +412,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
region.registerInterest(((Interest<K>) interest).getKey(), interest.getPolicy(),
interest.isDurable(), interest.isReceiveValues());
}
});
return region;
@@ -488,18 +442,8 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
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<K, V> extends RegionLookupFactoryBean<K, V>
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<K, V> 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<K, V> extends RegionLookupFactoryBean<K, V>
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<K, V> extends RegionLookupFactoryBean<K, V>
this.compressor = compressor;
}
public void setConcurrencyChecksEnabled(Boolean concurrencyChecksEnabled) {
this.concurrencyChecksEnabled = concurrencyChecksEnabled;
}
public void setConcurrencyLevel(Integer concurrencyLevel) {
this.concurrencyLevel = concurrencyLevel;
}
public void setCustomEntryIdleTimeout(CustomExpiry<K, V> customEntryIdleTimeout) {
this.customEntryIdleTimeout = customEntryIdleTimeout;
}
public void setCustomEntryTimeToLive(CustomExpiry<K, V> customEntryTimeToLive) {
this.customEntryTimeToLive = customEntryTimeToLive;
}
/**
* Sets the Data Policy. Used only when a new Region is created.
*
@@ -600,7 +574,6 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
setDataPolicy(resolvedDataPolicy);
}
/* (non-Javadoc) */
final boolean isDestroy() {
return this.destroy;
}
@@ -615,7 +588,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
*/
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<K, V> extends RegionLookupFactoryBean<K, V>
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<K, V> extends RegionLookupFactoryBean<K, V>
this.interests = interests;
}
/* (non-Javadoc) */
Interest<K>[] 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<K> 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<K, V> extends RegionLookupFactoryBean<K, V>
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<K, V> extends RegionLookupFactoryBean<K, V>
}
/**
* 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<K, V> extends RegionLookupFactoryBean<K, V>
}
/**
* 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<String> 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<RegionConfigurer> 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<V> valueConstraint) {

View File

@@ -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<String> regionNames() {
try {
return execute(new ListRegionsOnServerFunction());
}
catch (Exception ignore) {
try {
Object results = execute(new GetRegionsFunction());
List<String> regionNames = Collections.emptyList();
if (containsRegionInformation(results)) {
Object[] resultsArray = (Object[]) results;
regionNames = new ArrayList<String>(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> 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<String> 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));
}
}
}

View File

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

View File

@@ -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<Pool> 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<Pool> 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<Pool> 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<Pool> 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<Pool> 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<Pool> 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<Pool> 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<Pool> 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<Pool> 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<Pool> 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<Pool> 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<ConnectionEndpoint> locators) {
this.locators.add(locators);
}
/* (non-Javadoc) */
public void addServers(ConnectionEndpoint... servers) {
this.servers.add(servers);
}
/* (non-Javadoc) */
public void addServers(Iterable<ConnectionEndpoint> 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<Pool> implements
@Override
public List<InetSocketAddress> 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<Pool> 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<Pool> 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<Pool> implements
@Override
public void destroy(boolean keepAlive) {
try {
PoolFactoryBean.this.destroy();
}
@@ -553,70 +587,58 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport<Pool> 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<ConnectionEndpoint> 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<Pool> 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<ConnectionEndpoint> 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;
}

View File

@@ -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> T defaultIfNull(T defaultValue, ValueProvider<T> valueProvider) {
return (prefersPool() ? SpringUtils.defaultIfNull(valueProvider.getValue(), defaultValue) :
(defaultValue != null ? defaultValue : valueProvider.getValue()));
protected <T> T defaultIfNull(T defaultValue, Supplier<T> valueProvider) {
return prefersPool() ? SpringUtils.defaultIfNull(valueProvider.get(), defaultValue) :
(defaultValue != null ? defaultValue : valueProvider.get());
}
/* (non-Javadoc) */
protected <E, T extends Collection<E>> T defaultIfEmpty(T defaultValue, ValueProvider<T> valueProvider) {
protected <E, T extends Collection<E>> T defaultIfEmpty(T defaultValue, Supplier<T> 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<InetSocketAddress> getLocators(List<InetSocketAddress> 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<InetSocketAddress> getServers(List<InetSocketAddress> 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> {
T getValue();
}
}

View File

@@ -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 <code>null</code> {@link Pool} reference by returning
@@ -33,8 +33,9 @@ import org.apache.geode.cache.query.QueryService;
* when the {@link Pool} reference is <code>null</code>.
*
* @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<InetSocketAddress> 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<InetSocketAddress> 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<InetSocketAddress> 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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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;
@@ -30,6 +31,7 @@ import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.data.gemfire.config.support.CustomEditorBeanFactoryPostProcessor;
import org.springframework.data.gemfire.config.support.GemfireFeature;
import org.springframework.data.gemfire.config.support.PdxDiskStoreAwareBeanFactoryPostProcessor;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
@@ -45,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 {
@@ -62,79 +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<Element> txListeners = DomUtils.getChildElementsByTagName(element, "transaction-listener");
if (!CollectionUtils.isEmpty(txListeners)) {
ManagedList<Object> transactionListeners = new ManagedList<Object>();
ManagedList<Object> 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.throwExceptionIfNotGemfireV7(element.getLocalName(), "gateway-conflict-resolver", parserContext);
builder.addPropertyValue("gatewayConflictResolver", ParsingUtils.parseRefOrSingleNestedBeanDeclaration(
gatewayConflictResolver, parserContext, builder));
ParsingUtils.throwExceptionWhenGemFireFeatureUnavailable(GemfireFeature.WAN, element.getLocalName(),
"gateway-conflict-resolver", parserContext);
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");
@@ -146,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);
@@ -164,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");
@@ -211,17 +219,15 @@ class CacheParser extends AbstractSingleBeanDefinitionParser {
/**
* @param dynamicRegionSupport {@link BeanDefinitionBuilder} for &lt;gfe:dynamic-region-factory&gt; 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<Element> jndiBindings = DomUtils.getChildElementsByTagName(element, "jndi-binding");
if (!CollectionUtils.isEmpty(jndiBindings)) {
ManagedList<Object> jndiDataSources = new ManagedList<Object>(jndiBindings.size());
ManagedList<Object> jndiDataSources = new ManagedList<>(jndiBindings.size());
for (Element jndiBinding : jndiBindings) {
@@ -231,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<String, String> jndiAttributes = new ManagedMap<String, String>(attributes.getLength());
ManagedMap<String, String> jndiAttributes = new ManagedMap<>(attributes.getLength());
for (int index = 0, length = attributes.getLength(); index < length; index++) {
Attr attribute = (Attr) attributes.item(index);
@@ -243,9 +249,11 @@ class CacheParser extends AbstractSingleBeanDefinitionParser {
List<Element> jndiProps = DomUtils.getChildElementsByTagName(jndiBinding, "jndi-prop");
if (!CollectionUtils.isEmpty(jndiProps)) {
ManagedList<Object> props = new ManagedList<Object>(jndiProps.size());
ManagedList<Object> props = new ManagedList<>(jndiProps.size());
for (Element jndiProp : jndiProps) {
String key = jndiProp.getAttribute("key");
String type = jndiProp.getAttribute("type");
String value = jndiProp.getTextContent();
@@ -265,7 +273,7 @@ class CacheParser extends AbstractSingleBeanDefinitionParser {
jndiDataSources.add(jndiDataSource.getBeanDefinition());
}
builder.addPropertyValue("jndiDataSources", jndiDataSources);
cacheBuilder.addPropertyValue("jndiDataSources", jndiDataSources);
}
}
@@ -276,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");
}

View File

@@ -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");
}
/**

View File

@@ -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.
@@ -78,9 +82,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);
@@ -94,9 +98,10 @@ class ClientRegionParser extends AbstractRegionParser {
List<Element> subElements = DomUtils.getChildElements(element);
ManagedList<Object> interests = new ManagedList<Object>();
ManagedList<Object> interests = new ManagedList<>();
for (Element subElement : subElements) {
String subElementLocalName = subElement.getLocalName();
if ("cache-listener".equals(subElementLocalName)) {
@@ -128,8 +133,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)) {
@@ -138,28 +143,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"));

View File

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

View File

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

View File

@@ -18,8 +18,6 @@ package org.springframework.data.gemfire.config.xml;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geode.cache.LossAction;
import org.apache.geode.cache.MembershipAttributes;
import org.apache.geode.cache.ResumptionAction;
@@ -32,6 +30,7 @@ import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.core.Conventions;
import org.springframework.data.gemfire.GemfireUtils;
import org.springframework.data.gemfire.SubscriptionAttributesFactoryBean;
import org.springframework.data.gemfire.config.support.GemfireFeature;
import org.springframework.data.gemfire.eviction.EvictionAttributesFactoryBean;
import org.springframework.data.gemfire.expiration.ExpirationAttributesFactoryBean;
import org.springframework.data.gemfire.util.SpringUtils;
@@ -58,15 +57,13 @@ import org.w3c.dom.Element;
*/
abstract class ParsingUtils {
private static final Log log = LogFactory.getLog(ParsingUtils.class);
protected static final String CACHE_PROPERTY_NAME = "cache";
protected static final String REGION_PROPERTY_NAME = "region";
protected static final String CACHE_REF_ATTRIBUTE_NAME = "cache-ref";
protected static final String REGION_REF_ATTRIBUTE_NAME = "region-ref";
static void setPropertyReference(Element element, BeanDefinitionBuilder builder, String attributeName,
String propertyName) {
String propertyName) {
String attributeValue = element.getAttribute(attributeName);
@@ -81,7 +78,7 @@ abstract class ParsingUtils {
}
static void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attributeName,
String propertyName, Object defaultValue) {
String propertyName, Object defaultValue) {
String attributeValue = element.getAttribute(attributeName);
@@ -94,7 +91,8 @@ abstract class ParsingUtils {
}
static void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attributeName,
String propertyName) {
String propertyName) {
setPropertyValue(element, builder, attributeName, propertyName, null);
}
@@ -103,7 +101,7 @@ abstract class ParsingUtils {
}
static void setPropertyValue(BeanDefinitionBuilder builder, BeanDefinition source, String propertyName,
boolean withDependsOn) {
boolean withDependsOn) {
PropertyValue propertyValue = source.getPropertyValues().getPropertyValue(propertyName);
@@ -129,7 +127,7 @@ abstract class ParsingUtils {
if (!DomUtils.getChildElements(element).isEmpty()) {
parserContext.getReaderContext().error(String.format(
"Use either the '%1$s' attribute or a nested bean declaration for '%2$s' element, but not both.",
refAttributeName, element.getLocalName()), element);
refAttributeName, element.getLocalName()), element);
}
returnValue = new RuntimeBeanReference(refAttributeValue);
@@ -139,7 +137,7 @@ abstract class ParsingUtils {
}
static Object parseRefOrNestedCustomElement(Element element, ParserContext parserContext,
BeanDefinitionBuilder builder) {
BeanDefinitionBuilder builder) {
Object beanRef = ParsingUtils.getBeanReference(element, parserContext, "bean");
@@ -166,31 +164,31 @@ abstract class ParsingUtils {
* @return Bean reference or nested Bean definition.
*/
static Object parseRefOrNestedBeanDeclaration(Element element, ParserContext parserContext,
BeanDefinitionBuilder builder) {
BeanDefinitionBuilder builder) {
return parseRefOrNestedBeanDeclaration(element, parserContext, builder, "ref", false);
}
static Object parseRefOrNestedBeanDeclaration(Element element, ParserContext parserContext,
BeanDefinitionBuilder builder, String refAttributeName) {
BeanDefinitionBuilder builder, String refAttributeName) {
return parseRefOrNestedBeanDeclaration(element, parserContext, builder, refAttributeName, false);
}
static Object parseRefOrSingleNestedBeanDeclaration(Element element, ParserContext parserContext,
BeanDefinitionBuilder builder) {
BeanDefinitionBuilder builder) {
return parseRefOrNestedBeanDeclaration(element, parserContext, builder, "ref", true);
}
static Object parseRefOrSingleNestedBeanDeclaration(Element element, ParserContext parserContext,
BeanDefinitionBuilder builder, String refAttributeName) {
BeanDefinitionBuilder builder, String refAttributeName) {
return parseRefOrNestedBeanDeclaration(element, parserContext, builder, refAttributeName, true);
}
static Object parseRefOrNestedBeanDeclaration(Element element, ParserContext parserContext,
BeanDefinitionBuilder builder, String refAttributeName, boolean single) {
BeanDefinitionBuilder builder, String refAttributeName, boolean single) {
Object beanReference = getBeanReference(element, parserContext, refAttributeName);
@@ -211,7 +209,7 @@ abstract class ParsingUtils {
if (single) {
parserContext.getReaderContext().error(String.format(
"The element '%1$s' does not support multiple nested bean definitions.",
element.getLocalName()), element);
element.getLocalName()), element);
}
}
@@ -233,7 +231,7 @@ abstract class ParsingUtils {
* @return true if parsing actually occurred, false otherwise.
*/
static boolean parseEviction(Element element, ParserContext parserContext,
BeanDefinitionBuilder regionAttributesBuilder) {
BeanDefinitionBuilder regionAttributesBuilder) {
Element evictionElement = DomUtils.getChildElementByTagName(element, "eviction");
@@ -259,7 +257,7 @@ abstract class ParsingUtils {
return true;
}
return false;
return false;
}
/**
@@ -336,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");
@@ -357,18 +355,13 @@ abstract class ParsingUtils {
String concurrencyChecksEnabled = element.getAttribute("concurrency-checks-enabled");
if (StringUtils.hasText(concurrencyChecksEnabled)) {
if (GemfireUtils.isGemfireVersion7OrAbove()) {
ParsingUtils.setPropertyValue(element, regionAttributesBuilder, "concurrency-checks-enabled");
}
else {
log.warn("Setting 'concurrency-checks-enabled' is only available in Gemfire 7.0 or above!");
}
ParsingUtils.setPropertyValue(element, regionAttributesBuilder, "concurrency-checks-enabled");
}
}
@SuppressWarnings({ "deprecation", "unused" })
static void parseMembershipAttributes(Element element, ParserContext parserContext,
BeanDefinitionBuilder regionAttributesBuilder) {
BeanDefinitionBuilder regionAttributesBuilder) {
Element membershipAttributes = DomUtils.getChildElementByTagName(element, "membership-attributes");
@@ -393,17 +386,6 @@ abstract class ParsingUtils {
}
}
static void throwExceptionIfNotGemfireV7(String elementName, String attributeName, ParserContext parserContext) {
if (!GemfireUtils.isGemfireVersion7OrAbove()) {
String messagePrefix = (attributeName != null)
? String.format("Attribute '%1$s' of element '%2$s'", attributeName, elementName)
: String.format("Element '%1$s'", elementName);
parserContext.getReaderContext().error(
String.format("%1$s requires GemFire version 7 or later. The current version is %2$s.",
messagePrefix, GemfireUtils.GEMFIRE_VERSION), null);
}
}
static void parseScope(Element element, BeanDefinitionBuilder builder) {
String scopeAttributeValue = element.getAttribute("scope");
@@ -413,7 +395,7 @@ abstract class ParsingUtils {
}
private static boolean parseExpiration(Element rootElement, String elementName, String propertyName,
BeanDefinitionBuilder regionAttributesBuilder) {
BeanDefinitionBuilder regionAttributesBuilder) {
Element expirationElement = DomUtils.getChildElementByTagName(rootElement, elementName);
@@ -432,7 +414,7 @@ abstract class ParsingUtils {
}
private static boolean parseCustomExpiration(Element rootElement, ParserContext parserContext, String elementName,
String propertyName, BeanDefinitionBuilder regionAttributesBuilder) {
String propertyName, BeanDefinitionBuilder regionAttributesBuilder) {
Element expirationElement = DomUtils.getChildElementByTagName(rootElement, elementName);
@@ -449,7 +431,7 @@ abstract class ParsingUtils {
}
static void parseCompressor(Element element, ParserContext parserContext,
BeanDefinitionBuilder regionAttributesBuilder) {
BeanDefinitionBuilder regionAttributesBuilder) {
Element compressorElement = DomUtils.getChildElementByTagName(element, "compressor");
@@ -459,6 +441,14 @@ abstract class ParsingUtils {
}
}
@SuppressWarnings("unused")
static void assertGemFireFeatureAvailable(Element element, ParserContext parserContext) {
if (GemfireUtils.isGemfireFeatureUnavailable(element)) {
parserContext.getReaderContext().error(String.format("'%1$s' is not supported in %2$s v%3$s",
element.getLocalName(), GemfireUtils.GEMFIRE_NAME, GemfireUtils.GEMFIRE_VERSION), element);
}
}
static void setCacheReference(Element element, BeanDefinitionBuilder builder) {
builder.addPropertyReference(CACHE_PROPERTY_NAME, resolveCacheReference(element));
}
@@ -478,4 +468,17 @@ abstract class ParsingUtils {
static String resolveRegionReference(Element element) {
return element.getAttribute(REGION_REF_ATTRIBUTE_NAME);
}
static void throwExceptionWhenGemFireFeatureUnavailable(GemfireFeature feature,
String elementName, String attributeName, ParserContext parserContext) {
if (GemfireUtils.isGemfireFeatureUnavailable(feature)) {
String messagePrefix = (attributeName != null)
? String.format("Attribute '%1$s' of element '%2$s'", attributeName, elementName)
: String.format("Element '%1$s'", elementName);
parserContext.getReaderContext().error(
String.format("%1$s requires GemFire version 7 or later. The current version is %2$s.",
messagePrefix, GemfireUtils.GEMFIRE_VERSION), null);
}
}
}

View File

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

View File

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

View File

@@ -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<Class<? extends Annotation>> functionExecutionAnnotationTypes;
static {
Set<Class<? extends Annotation>> annotationTypes = new HashSet<Class<? extends Annotation>>(5);
Set<Class<? extends Annotation>> 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<Class<? extends Annotation>> getFunctionExecutionAnnotationTypes() {
return functionExecutionAnnotationTypes;
}
static Set<String> getFunctionExecutionAnnotationTypeNames() {
Set<String> functionExecutionTypeNames = new HashSet<String>(getFunctionExecutionAnnotationTypes().size());
for (Class<? extends Annotation> 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<ScannedGenericBeanDefinition> 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<ScannedGenericBeanDefinition> result = new HashSet<ScannedGenericBeanDefinition>();
Set<ScannedGenericBeanDefinition> result = new HashSet<>();
for (String basePackage : getBasePackages()) {
if (logger.isDebugEnabled()) {
logger.debug("scanning package " + basePackage);
}
Collection<BeanDefinition> 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;
}
}

View File

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

View File

@@ -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 &lt;function-executions&gt; definitions.
* Parser for a &lt;function-executions&gt; 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;
}
}

View File

@@ -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<String> 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<String> functionExecutionAnnotationTypeNames) {
Set<String> 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;
}
}

View File

@@ -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<String,Object> attributes;
private final Map<String, Object> 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<String, Object> getAttributes() {
return this.attributes;
return this.annotationAttributes;
}
Class<?> getFunctionExecutionInterface() {
return this.functionExecutionInterface;
}
}

View File

@@ -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<String> getBasePackages();
/**
* Returns configured {@link TypeFilter}s
* @return include filters
@@ -50,4 +55,12 @@ interface FunctionExecutionConfigurationSource {
*/
Iterable<TypeFilter> 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();
}

View File

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

View File

@@ -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<TypeFilter> parseTypeFilters(Element element, Type type) {
Collection<TypeFilter> filters = new HashSet<>();
NodeList nodeList = element.getChildNodes();
Collection<TypeFilter> filters = new HashSet<TypeFilter>();
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<Annotation>) 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;
}
}

View File

@@ -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<TypeFilter> includeFilters;
private Iterable<TypeFilter> 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<TypeFilter> includeFilters;
private final Iterable<TypeFilter> 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<String> 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<TypeFilter> getIncludeFilters() {
return includeFilters;
return this.includeFilters;
}
/* (non-Javadoc)
@@ -75,7 +87,6 @@ class XmlFunctionExecutionConfigurationSource extends AbstractFunctionExecutionC
*/
@Override
public Iterable<TypeFilter> getExcludeFilters() {
return excludeFilters;
return this.excludeFilters;
}
}

View File

@@ -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;
}
<T> Iterable<T> execute() {
@@ -92,21 +95,22 @@ abstract class AbstractFunctionExecution {
@SuppressWarnings("unchecked")
<T> Iterable<T> 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<T> results = null;
@@ -126,11 +130,8 @@ abstract class AbstractFunctionExecution {
try {
results = (Iterable<T>) 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> T executeAndExtract() {
Iterable<T> 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 <T> Iterable<T> replaceSingletonNullCollectionWithEmptyList(Iterable<T> results) {
if (results != null) {
Iterator<T> it = results.iterator();
if (!it.hasNext()) {
@@ -212,11 +216,10 @@ abstract class AbstractFunctionExecution {
}
if (it.next() == null && !it.hasNext()) {
return new ArrayList<T>();
return Collections.emptyList();
}
}
return results;
}
}

View File

@@ -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<Object>, MethodInterceptor, BeanClassLoaderAware {
public class GemfireFunctionProxyFactoryBean implements BeanClassLoaderAware, FactoryBean<Object>, MethodInterceptor {
private volatile ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
@@ -56,6 +60,7 @@ public class GemfireFunctionProxyFactoryBean implements FactoryBean<Object>, 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<Object>, 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<Object>, 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<Object>, 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;
}
}
}

View File

@@ -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 <T> Iterable<T> execute(Function function, Set<?> keys, Object... args) {
return execute(new RegionFunctionExecution(region).setKeys(keys).setFunction(function).setTimeout(timeout)
.setArgs(args));
}
@Override
public <T> Iterable<T> execute(String functionId, Set<?> keys, Object... args) {
return execute(new RegionFunctionExecution(region).setKeys(keys).setFunctionId(functionId).setTimeout(timeout)
.setArgs(args));
}
@Override
public <T> T executeAndextract(String functionId, Set<?> keys, Object... args) {
return this.<T> 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 <T> Iterable<T> execute(Function function, Set<?> keys, Object... args) {
return execute(getFunctionExecution()
.setKeys(keys)
.setFunction(function)
.setTimeout(this.timeout)
.setArgs(args));
}
@Override
public <T> Iterable<T> execute(String functionId, Set<?> keys, Object... args) {
return execute(getFunctionExecution()
.setKeys(keys).setFunctionId(functionId)
.setTimeout(this.timeout)
.setArgs(args));
}
@Override
public <T> 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);
}
}

View File

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

View File

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

View File

@@ -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.<GemFireCache>ofNullable(getClientCache()).orElseGet(CacheUtils::getCache);
}

View File

@@ -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 &lt;gfe:*-region&gt; 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 &lt;gfe:*-region&gt; 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);

View File

@@ -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<String> 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<String> supplier) {
return StringUtils.hasText(value) ? value : supplier.get();
}
/* (non-Javadoc) */
public static <T> T defaultIfNull(T value, T defaultValue) {
return Optional.ofNullable(value).orElse(defaultValue);
return defaultIfNull(value, () -> defaultValue);
}
/* (non-Javadoc) */
public static <T> T defaultIfNull(T value, Supplier<T> 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> T safeGetValue(Supplier<T> valueSupplier) {
return safeGetValue(valueSupplier, (T) null);
}
/* (non-Javadoc) */
public static <T> T safeGetValue(Supplier<T> valueSupplier, T defaultValue) {
return safeGetValue(valueSupplier, (Supplier<T>) () -> defaultValue);
}
/* (non-Javadoc) */
public static <T> T safeGetValue(Supplier<T> valueSupplier, Supplier<T> defaultValueSupplier) {
return safeGetValue(valueSupplier, (Function<Throwable, T>) exception -> defaultValueSupplier.get());
}
/* (non-Javadoc) */
public static <T> T safeGetValue(Supplier<T> valueSupplier, Function<Throwable, T> exceptionHandler) {
try {
return valueSupplier.get();
}

View File

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

View File

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

View File

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

View File

@@ -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,9 +47,9 @@ 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.ProcessInputStreamListener;
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;
@@ -70,7 +72,7 @@ import org.springframework.util.StringUtils;
* @since 1.5.0
*/
@SuppressWarnings("unused")
public class CacheClusterConfigurationIntegrationTest {
public class CacheClusterConfigurationIntegrationTest extends ClientServerIntegrationTestsSupport {
private static File locatorWorkingDirectory;
@@ -78,11 +80,14 @@ public class CacheClusterConfigurationIntegrationTest {
private static List<String> locatorProcessOutput = Collections.synchronizedList(new ArrayList<String>());
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));
@@ -90,36 +95,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());
@@ -131,12 +142,12 @@ public class CacheClusterConfigurationIntegrationTest {
List<String> arguments = new ArrayList<String>();
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(new ProcessInputStreamListener() {
@@ -149,66 +160,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);
@@ -228,17 +257,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"));
}
}
}

View File

@@ -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,37 +95,27 @@ public class CacheFactoryBeanTest {
@Mock
private Cache mockCache;
@Rule
public ExpectedException exception = ExpectedException.none();
@Test
public void afterPropertiesSet() throws Exception {
public void afterPropertiesSetAppliesCacheConfigurersAndThenInitializesBeanFactoryLocator() throws Exception {
AtomicBoolean postProcessBeforeCacheInitializationCalled = new AtomicBoolean(false);
CacheFactoryBean cacheFactoryBean = spy(new CacheFactoryBean());
Properties gemfireProperties = new Properties();
CacheFactoryBean cacheFactoryBean = 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() {
public void applyingCacheConfigurersDisablesAutoReconnectAndDoesNotUseClusterConfigurationByDefault() {
Properties gemfireProperties = new Properties();
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean();
new CacheFactoryBean().postProcessBeforeCacheInitialization(gemfireProperties);
cacheFactoryBean.applyCacheConfigurers();
Properties gemfireProperties = cacheFactoryBean.getProperties();
assertThat(gemfireProperties.size(), is(equalTo(2)));
assertThat(gemfireProperties.containsKey("disable-auto-reconnect"), is(true));
@@ -134,15 +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));
@@ -152,15 +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));
@@ -170,15 +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));
@@ -187,13 +178,31 @@ public class CacheFactoryBeanTest {
assertThat(gemfireProperties.getProperty("use-cluster-configuration"), is(equalTo("true")));
}
@Test
public void applyCacheConfigurersWithAutoReconnectEnabledAndClusterConfigurationDisabled() {
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 {
Cache mockCache = mock(Cache.class);
AtomicBoolean initCalled = new AtomicBoolean(false);
Cache mockCache = mock(Cache.class);
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean() {
@Override Cache init() {
initCalled.set(true);
@@ -339,6 +348,7 @@ public class CacheFactoryBeanTest {
Cache mockCache = mock(Cache.class);
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean() {
@Override @SuppressWarnings("unchecked ")
protected <T extends GemFireCache> T fetchCache() {
return (T) mockCache;
@@ -441,7 +451,7 @@ public class CacheFactoryBeanTest {
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));
@@ -461,7 +471,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));
@@ -483,7 +493,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));
@@ -493,26 +503,7 @@ public class CacheFactoryBeanTest {
}
@Test
public void createCacheWithExistingCache() throws Exception {
CacheFactory mockCacheFactory = mock(CacheFactory.class);
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean();
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() {
public void createCacheWithCacheFactory() {
CacheFactory mockCacheFactory = mock(CacheFactory.class);
@@ -530,6 +521,7 @@ public class CacheFactoryBeanTest {
@Test(expected = IllegalArgumentException.class)
public void postProcessCacheWithInvalidCriticalHeapPercentage() throws Exception {
try {
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean();
@@ -549,6 +541,7 @@ public class CacheFactoryBeanTest {
@Test(expected = IllegalArgumentException.class)
public void postProcessCacheWithInvalidCriticalOffHeapPercentage() throws Exception {
try {
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean();
@@ -568,6 +561,7 @@ public class CacheFactoryBeanTest {
@Test(expected = IllegalArgumentException.class)
public void postProcessCacheWithInvalidEvictionHeapPercentage() throws Exception {
try {
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean();
@@ -587,6 +581,7 @@ public class CacheFactoryBeanTest {
@Test(expected = IllegalArgumentException.class)
public void postProcessCacheWithInvalidEvictionOffHeapPercentage() throws Exception {
try {
CacheFactoryBean cacheFactoryBean = new CacheFactoryBean();

View File

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

View File

@@ -86,7 +86,7 @@ public class GemfireUtilsTest {
}
@Test
public void isDurableWhenNotDurableClientIsFalse() {
public void isDurableWithNonDurableClientIsFalse() {
ClientCache mockClientCache = mock(ClientCache.class);

View File

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

View File

@@ -50,7 +50,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;
/**
@@ -66,7 +66,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 {
@@ -74,7 +74,8 @@ public class LookupRegionMutationIntegrationTest {
@Resource(name = "Example")
private Region<?, ?> example;
protected void assertCacheListeners(CacheListener[] cacheListeners, Collection<String> expectedCacheListenerNames) {
private void assertCacheListeners(CacheListener[] cacheListeners, Collection<String> expectedCacheListenerNames) {
if (!expectedCacheListenerNames.isEmpty()) {
assertNotNull("CacheListeners must not be null!", cacheListeners);
assertEquals(expectedCacheListenerNames.size(), cacheListeners.length);
@@ -82,26 +83,55 @@ 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 assertGemFireComponent(Object gemfireComponent, String expectedName) {
private void assertGatewaySenders(Region<?, ?> region, List<String> expectedGatewaySenderIds) {
assertNotNull(region.getAttributes());
assertNotNull(region.getAttributes().getGatewaySenderIds());
assertEquals(expectedGatewaySenderIds.size(), region.getAttributes().getGatewaySenderIds().size());
assertTrue(expectedGatewaySenderIds.containsAll(region.getAttributes().getGatewaySenderIds()));
}
private void assertGemFireComponent(Object gemfireComponent, String expectedName) {
assertNotNull("The GemFire component must not be null!", gemfireComponent);
assertEquals(expectedName, gemfireComponent.toString());
}
protected Collection<String> toStrings(Object[] objects) {
private void assertRegionAttributes(Region<?, ?> region, String expectedName, DataPolicy expectedDataPolicy) {
assertRegionAttributes(region, expectedName, String.format("%1$s%2$s", Region.SEPARATOR, expectedName),
expectedDataPolicy);
}
private void assertRegionAttributes(Region<?, ?> region, String expectedName, String expectedFullPath,
DataPolicy expectedDataPolicy) {
assertNotNull(String.format("'%1$s' Region was not properly initialized!", region));
assertEquals(expectedName, region.getName());
assertEquals(expectedFullPath, region.getFullPath());
assertNotNull(region.getAttributes());
assertEquals(expectedDataPolicy, region.getAttributes().getDataPolicy());
}
private Collection<String> toStrings(Object[] objects) {
List<String> cacheListenerNames = new ArrayList<String>(objects.length);
for (Object object : objects) {
@@ -113,11 +143,8 @@ public class LookupRegionMutationIntegrationTest {
@Test
public void testRegionConfiguration() {
assertNotNull("'/Example' Region was not properly initialized!", example);
assertEquals("Example", example.getName());
assertEquals("/Example", example.getFullPath());
assertNotNull(example.getAttributes());
assertEquals(DataPolicy.REPLICATE, example.getAttributes().getDataPolicy());
assertRegionAttributes(example, "Example", DataPolicy.REPLICATE);
assertEquals(13, example.getAttributes().getInitialCapacity());
assertEquals(0.85f, example.getAttributes().getLoadFactor(), 0.0f);
assertCacheListeners(example.getAttributes().getCacheListeners(), Arrays.asList("A", "B"));
@@ -232,11 +259,12 @@ public class LookupRegionMutationIntegrationTest {
public static final class TestCustomExpiry<K, V> extends AbstractNameable implements CustomExpiry<K, V> {
@Override public ExpirationAttributes getExpiry(Region.Entry<K, V> entry) {
@Override
public ExpirationAttributes getExpiry(Region.Entry<K, V> entry) {
throw new UnsupportedOperationException("Not Implemented!");
}
@Override public void close() { }
@Override
public void close() { }
}
}

View File

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

View File

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

View File

@@ -131,7 +131,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());
}
};
@@ -180,53 +180,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() {
@@ -243,26 +196,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() {
@@ -790,7 +723,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 {
@@ -810,7 +743,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 {
@@ -830,7 +763,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 {
@@ -871,7 +804,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 {
@@ -912,7 +845,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 {
@@ -935,7 +868,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 {
@@ -1021,7 +954,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 {
@@ -1043,7 +976,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 {
@@ -1121,7 +1054,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 {
@@ -1143,7 +1076,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 {

View File

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

View File

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

View File

@@ -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<String, PoolFactoryBean> 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<String, PoolFactoryBean> 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<String, PoolFactoryBean> 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<String, PoolFactoryBean> 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

View File

@@ -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;
@@ -74,32 +71,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);
@@ -120,19 +121,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);
@@ -141,12 +129,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));
@@ -156,6 +143,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));
@@ -164,13 +152,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));
}
@@ -178,34 +165,37 @@ public class ClientRegionFactoryBeanTest {
@SuppressWarnings({ "deprecation", "unchecked" })
public void createRegionUsingDefaultPersistentShortcut() throws Exception {
BeanFactory mockBeanFactory = mock(BeanFactory.class);
ClientCache mockClientCache = mock(ClientCache.class);
ClientRegionFactory<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class);
Pool mockPool = mock(Pool.class);
Region<Object, Object> mockRegion = mock(Region.class);
RegionAttributes<Object, Object> 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<Object, Object> 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));
}
@@ -230,7 +220,7 @@ public class ClientRegionFactoryBeanTest {
Region<Object, Object> actualRegion = factoryBean.createRegion(mockClientCache, "TestRegion");
assertSame(mockRegion, actualRegion);
assertThat(actualRegion).isEqualTo(mockRegion);
verifyZeroInteractions(mockBeanFactory);
verify(mockClientCache, times(1))
@@ -240,7 +230,7 @@ public class ClientRegionFactoryBeanTest {
@Test
@SuppressWarnings("unchecked")
public void createRegionWithSubRegionCreation() throws Exception {
public void createRegionAsSubRegion() throws Exception {
BeanFactory mockBeanFactory = mock(BeanFactory.class);
@@ -260,7 +250,7 @@ public class ClientRegionFactoryBeanTest {
Region<Object, Object> actualRegion = factoryBean.createRegion(mockClientCache, "TestSubRegion");
assertSame(mockSubRegion, actualRegion);
assertThat(actualRegion).isEqualTo(mockSubRegion);
verifyZeroInteractions(mockBeanFactory);
verify(mockClientCache, times(1))
@@ -271,108 +261,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<Object, Object> 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<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class);
Pool mockPool = mock(Pool.class);
RegionAttributes<Object, Object> 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<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class);
Pool mockPool = mock(Pool.class);
RegionAttributes<Object, Object> 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<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class);
RegionAttributes<Object, Object> 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<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class);
RegionAttributes<Object, Object> 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<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class);
RegionAttributes<Object, Object> 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);
@@ -386,9 +410,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();
@@ -396,7 +419,7 @@ public class ClientRegionFactoryBeanTest {
@Test
@SuppressWarnings("unchecked")
public void doesNotConfigurePoolFromRegionAttributesWhenPoolIsEmpty() {
public void doesNotConfigurePoolWhenDeclaredPoolIsEmpty() {
BeanFactory mockBeanFactory = mock(BeanFactory.class);
@@ -408,12 +431,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();
@@ -421,7 +443,7 @@ public class ClientRegionFactoryBeanTest {
@Test
@SuppressWarnings("unchecked")
public void doesNotConfigurePoolFromRegionAttributesWhenPoolIsNull() {
public void doesNotConfigurePoolWhenDeclaredPoolIsNull() {
BeanFactory mockBeanFactory = mock(BeanFactory.class);
@@ -432,190 +454,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<Object, Object> 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<Object, Object> 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<Object, Object> 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<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class);
RegionAttributes<Object, Object> 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<Object, Object> 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<Object, Object> 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<Object, Object> 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<Object, Object> 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
@@ -660,22 +507,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() {

View File

@@ -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<String, Integer> 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> T valueBeforeAndAfterDirtiesContext(T before, T after) {
private <T> 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()) {

View File

@@ -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<String> 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<String> arguments = new ArrayList<String>();
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");
}
}

View File

@@ -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<String> regionList = Arrays.asList(applicationContext.getBeanNamesForType(Region.class));
List<String> 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<Person> result = repository.findById(1L);
assertThat(result.isPresent()).isTrue();
assertThat(result.get().getFirstname()).isEqualTo("Dave");
assertThat(result.map(Person::getFirstname).orElse(null)).isEqualTo("Dave");
}
}

View File

@@ -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<String> arguments = new ArrayList<String>(5);
List<String> 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

View File

@@ -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<Object, Object> mockRegion(String name) {
private Region<Object, Object> mockRegion(String name) {
Region<Object, Object> mockRegion = mock(Region.class, name);
RegionAttributes<Object, Object> mockRegionAttributes = mock(RegionAttributes.class,
String.format("%1$s-RegionAttributes", name));
RegionAttributes<Object, Object> 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 <T> List<T> asList(Iterable<T> iterable) {
List<T> list = new ArrayList<T>();
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<String> testRegionNames = Collections.singletonList("Test");
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(null) {
@Override Iterable<String> regionNames() {
AtomicBoolean createClientRegionProxiesCalled = new AtomicBoolean(false);
ConfigurableListableBeanFactory mockBeanFactory =
mock(ConfigurableListableBeanFactory.class, "MockSpringBeanFactory");
List<String> testRegionNames = Collections.singletonList("Test");
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache) {
@Override
Iterable<String> regionNames() {
return testRegionNames;
}
@@ -126,10 +139,13 @@ public class GemfireDataSourcePostProcessorTest {
@Test
public void regionNamesWithListRegionsOnServerFunction() {
final List<String> expectedRegionNames = Arrays.asList("ExampleOne", "ExampleTwo");
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(null) {
@Override @SuppressWarnings("unchecked") <T> T execute(Function gemfireFunction, Object... arguments) {
List<String> expectedRegionNames = Arrays.asList("ExampleOne", "ExampleTwo");
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache) {
@Override @SuppressWarnings("unchecked")
<T> 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<String> expectedRegionNames = Arrays.asList("ExampleOne", "ExampleTwo");
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(null) {
@Override @SuppressWarnings("unchecked") <T> T execute(Function gemfireFunction, Object... arguments) {
List<String> expectedRegionNames = Arrays.asList("ExampleOne", "ExampleTwo");
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache) {
@Override @SuppressWarnings("unchecked")
<T> 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<String> actualRegionNames = postProcessor.regionNames();
List<String> 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> T execute(Function gemfireFunction, Object... arguments) {
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache) {
@Override @SuppressWarnings("unchecked") <T> 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> T execute(Function gemfireFunction, Object... arguments) {
AtomicBoolean logMethodCalled = new AtomicBoolean(false);
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache) {
@Override @SuppressWarnings("unchecked") <T> 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));
}
}
}

View File

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

View File

@@ -237,7 +237,7 @@ public class SpELExpressionConfiguredPoolsIntegrationTests {
}
@Override
boolean isDistributedSystemPresent() {
boolean isClientCachePresent() {
return true;
}
}

View File

@@ -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<Object> defaultList = Collections.singletonList("default");
assertThat(this.poolAdapter.prefersDefault(), is(true));
assertThat((List<Object>) this.poolAdapter.defaultIfEmpty(defaultList, this.mockValueProvider), is(equalTo(defaultList)));
assertThat((List<Object>) this.poolAdapter.defaultIfEmpty(defaultList, this.mockSupplier), is(equalTo(defaultList)));
verifyZeroInteractions(this.mockValueProvider);
verifyZeroInteractions(this.mockSupplier);
}
@Test
@@ -227,12 +228,12 @@ public class DefaultableDelegatingPoolAdapterTest {
List<Object> poolList = Collections.singletonList("pool");
when(this.mockValueProvider.getValue()).thenReturn(poolList);
when(this.mockSupplier.get()).thenReturn(poolList);
assertThat(this.poolAdapter.prefersDefault(), is(true));
assertThat((List<Object>) this.poolAdapter.defaultIfEmpty(null, this.mockValueProvider), is(equalTo(poolList)));
assertThat((List<Object>) 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<Object> poolList = Collections.singletonList("pool");
when(this.mockValueProvider.getValue()).thenReturn(poolList);
when(this.mockSupplier.get()).thenReturn(poolList);
assertThat(this.poolAdapter.prefersDefault(), is(true));
assertThat((List<Object>) this.poolAdapter.defaultIfEmpty(Collections.emptyList(), this.mockValueProvider),
assertThat((List<Object>) 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<Object> poolList = Collections.singletonList("pool");
when(this.mockValueProvider.getValue()).thenReturn(poolList);
when(this.mockSupplier.get()).thenReturn(poolList);
assertThat(this.poolAdapter.prefersPool(), is(true));
assertThat((List<Object>) this.poolAdapter.defaultIfEmpty(Collections.<Object>singletonList("default"), this.mockValueProvider),
assertThat((List<Object>) this.poolAdapter.defaultIfEmpty(Collections.<Object>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<Object> defaultList = Collections.singletonList("default");
assertThat(this.poolAdapter.prefersPool(), is(true));
assertThat((List<Object>) this.poolAdapter.defaultIfEmpty(defaultList, this.mockValueProvider),
assertThat((List<Object>) 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<Object> defaultList = Collections.singletonList("default");
assertThat(this.poolAdapter.prefersPool(), is(true));
assertThat((List<Object>) this.poolAdapter.defaultIfEmpty(defaultList, this.mockValueProvider),
assertThat((List<Object>) this.poolAdapter.defaultIfEmpty(defaultList, this.mockSupplier),
is(equalTo(defaultList)));
verify(this.mockValueProvider, times(1)).getValue();
verify(this.mockSupplier, times(1)).get();
}
@Test

View File

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

View File

@@ -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<ClientCache>, InitializingBean {
static final AtomicReference<Region> MOCK_REGION_REF = new AtomicReference<Region>(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<Object, Object> {
@Override
@@ -350,12 +315,11 @@ public class ClientRegionNamespaceTest {
}
@Override
public void close() {
}
public void close() { }
}
public static final class TestCacheWriter extends CacheWriterAdapter<Object, Object> {
}
public static final class TestCacheWriter extends CacheWriterAdapter<Object, Object> { }
public static class TestCompressor implements Compressor {

View File

@@ -38,9 +38,7 @@ import org.apache.geode.cache.wan.GatewaySender;
import org.apache.geode.cache.wan.GatewaySender.OrderPolicy;
import org.apache.geode.cache.wan.GatewayTransportFilter;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.gemfire.GemfireUtils;
import org.springframework.data.gemfire.RecreatingContextTest;
import org.springframework.data.gemfire.RegionFactoryBean;
import org.springframework.data.gemfire.TestUtils;
@@ -70,14 +68,6 @@ public class GemfireV7GatewayNamespaceTest extends RecreatingContextTest {
ctx.getBeanFactory().addBeanPostProcessor(new GemfireTestBeanPostProcessor());
}
@Before
@Override
public void createCtx() {
if (GemfireUtils.isGemfireVersion7OrAbove()) {
super.createCtx();
}
}
@AfterClass
public static void tearDown() {
for (String name : new File(".").list(new FilenameFilter() {
@@ -272,5 +262,4 @@ public class GemfireV7GatewayNamespaceTest extends RecreatingContextTest {
return false;
}
}
}

View File

@@ -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<K, V> extends RegionFactoryBean<K, V> {
}
public static final class TestRegionFactoryBean<K, V> extends RegionFactoryBean<K, V> { }
}

View File

@@ -69,7 +69,8 @@ public class ReplicatedRegionNamespaceTest {
assertTrue(applicationContext.containsBean("simple"));
RegionFactoryBean simpleRegionFactoryBean = applicationContext.getBean("&simple", RegionFactoryBean.class);
RegionFactoryBean simpleRegionFactoryBean =
applicationContext.getBean("&simple", RegionFactoryBean.class);
assertEquals("simple", TestUtils.readField("beanName", simpleRegionFactoryBean));
assertEquals(false, TestUtils.readField("close", simpleRegionFactoryBean));
@@ -89,7 +90,8 @@ public class ReplicatedRegionNamespaceTest {
assertTrue(applicationContext.containsBean("pub"));
RegionFactoryBean publisherRegionFactoryBean = applicationContext.getBean("&pub", RegionFactoryBean.class);
RegionFactoryBean publisherRegionFactoryBean =
applicationContext.getBean("&pub", RegionFactoryBean.class);
assertTrue(publisherRegionFactoryBean instanceof ReplicatedRegionFactoryBean);
assertEquals("publisher", TestUtils.readField("name", publisherRegionFactoryBean));
@@ -107,7 +109,8 @@ public class ReplicatedRegionNamespaceTest {
assertTrue(applicationContext.containsBean("complex"));
RegionFactoryBean complexRegionFactoryBean = applicationContext.getBean("&complex", RegionFactoryBean.class);
RegionFactoryBean complexRegionFactoryBean =
applicationContext.getBean("&complex", RegionFactoryBean.class);
assertNotNull(complexRegionFactoryBean);
assertEquals("complex", TestUtils.readField("beanName", complexRegionFactoryBean));
@@ -179,7 +182,8 @@ public class ReplicatedRegionNamespaceTest {
assertTrue(applicationContext.containsBean("lookup"));
RegionLookupFactoryBean regionLookupFactoryBean = applicationContext.getBean("&lookup", RegionLookupFactoryBean.class);
RegionLookupFactoryBean regionLookupFactoryBean =
applicationContext.getBean("&lookup", RegionLookupFactoryBean.class);
assertNotNull(regionLookupFactoryBean);
assertEquals("existing", TestUtils.readField("name", regionLookupFactoryBean));

View File

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

View File

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

View File

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

View File

@@ -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<String> arguments = new ArrayList<String>();
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"));
}
}
}

View File

@@ -70,18 +70,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<Object> 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);
@@ -98,7 +101,7 @@ public class AbstractFunctionExecutionTest {
assertThat(actualResults, is(notNullValue()));
assertThat(actualResults, is(equalTo((Iterable<Object>) 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));
@@ -177,8 +180,11 @@ public class AbstractFunctionExecutionTest {
@Test
public void executeAndExtractWithThrowsException() {
AbstractFunctionExecution functionExecution = new AbstractFunctionExecution() {
@Override protected Execution getExecution() {
@Override
protected Execution getExecution() {
return mockExecution;
}
@@ -190,7 +196,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();
}

View File

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

View File

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

View File

@@ -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) */

View File

@@ -73,6 +73,7 @@ public abstract class ThreadUtils {
}
// TODO rename interface to Condition and waiting() method to evaluate()
@FunctionalInterface
public interface WaitCondition {
boolean waiting();
}

View File

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

View File

@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>

View File

@@ -1,7 +1,9 @@
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 8.0//EN"
"http://www.gemstone.com/dtd/cache8_0.dtd">
<cache>
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://geode.apache.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd"
version="1.0">
<region name="NativeLocalRegion" refid="LOCAL">
<region-attributes initial-capacity="1" load-factor="0.95">
<key-constraint>java.lang.Integer</key-constraint>
@@ -20,4 +22,5 @@
<value-constraint>java.lang.String</value-constraint>
</region-attributes>
</region>
</cache>

View File

@@ -1,22 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
">
<context:property-placeholder/>
<util:properties id="gemfireProperties">
<prop key="name">CacheUsingSharedConfigurationIntegrationTest</prop>
<prop key="mcast-port">0</prop>
<prop key="log-level">warning</prop>
<prop key="locators">localhost[20668]</prop>
<prop key="log-level">error</prop>
<prop key="locators">localhost[${spring.data.gemfire.locator.port:20668}]</prop>
</util:properties>
<gfe:cache cache-xml-location="/clusterconfig-cache.xml" properties-ref="gemfireProperties"
<gfe:cache cache-xml-location="/non-cluster-config-cache.xml" properties-ref="gemfireProperties"
use-bean-factory-locator="false" use-cluster-configuration="true"/>
<gfe:lookup-region id="ClusterConfigRegion"/>

View File

@@ -1,22 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
">
<context:property-placeholder/>
<util:properties id="gemfireProperties">
<prop key="name">CacheNotUsingSharedConfigurationIntegrationTest</prop>
<prop key="mcast-port">0</prop>
<prop key="log-level">warning</prop>
<prop key="locators">localhost[20668]</prop>
<prop key="log-level">error</prop>
<prop key="locators">localhost[${spring.data.gemfire.locator.port:20668}]</prop>
</util:properties>
<gfe:cache cache-xml-location="/clusterconfig-cache.xml" properties-ref="gemfireProperties"
<gfe:cache cache-xml-location="/non-cluster-config-cache.xml" properties-ref="gemfireProperties"
use-bean-factory-locator="false" use-cluster-configuration="false"/>
<!-- Should throw an Exception! -->

View File

@@ -3,25 +3,19 @@
xmlns:context="http://www.springframework.org/schema/context"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:gfe-data="http://www.springframework.org/schema/data/gemfire"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/data/gemfire http://www.springframework.org/schema/data/gemfire/spring-data-gemfire.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
">
<util:properties id="client.properties">
<prop key="gemfire.client.server.host">localhost</prop>
<prop key="gemfire.client.server.port">42084</prop>
</util:properties>
<context:property-placeholder properties-ref="client.properties"/>
<context:property-placeholder/>
<gfe-data:datasource min-connections="1" max-connections="1">
<gfe-data:server host="${gemfire.client.server.host}" port="${gemfire.client.server.port}"/>
<gfe-data:server host="${spring.data.gemfire.cache.server.host:localhost}"
port="${spring.data.gemfire.cache.server.port:40404}"/>
</gfe-data:datasource>
<gfe:client-region id="ClientOnlyRegion" shortcut="LOCAL"/>

View File

@@ -2,31 +2,19 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
">
<util:properties id="serverProperties">
<prop key="gemfire.cache.server.host">localhost</prop>
<prop key="gemfire.cache.server.port">42084</prop>
</util:properties>
<context:property-placeholder/>
<context:property-placeholder properties-ref="serverProperties"/>
<gfe:cache/>
<util:properties id="gemfireProperties">
<prop key="name">GemFireDataSourceIntegrationTestServer</prop>
<prop key="mcast-port">0</prop>
<prop key="log-level">warning</prop>
</util:properties>
<gfe:cache properties-ref="gemfireProperties"/>
<gfe:cache-server bind-address="${gemfire.cache.server.host}" port="${gemfire.cache.server.port}"
<gfe:cache-server bind-address="${spring.data.gemfire.cache.server.host:localhost}"
port="${spring.data.gemfire.cache.server.port:40404}"
auto-startup="true" max-connections="1"/>
<gfe:replicated-region id="ClientServerRegion" persistent="false"/>

View File

@@ -4,16 +4,16 @@
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
default-lazy-init="true">
default-lazy-init="true">
<bean class="org.springframework.data.gemfire.test.GemfireTestBeanPostProcessor"/>
<util:properties id="gemfireProperties">
<prop key="disable-tcp">false</prop>
<prop key="log-level">warning</prop>
<prop key="log-level">error</prop>
</util:properties>
<gfe:cache/>
@@ -33,12 +33,16 @@
<gfe:cache id="cache-with-auto-reconnect-enabled" properties-ref="gemfireProperties" enable-auto-reconnect="true"/>
<gfe:cache id="cache-with-no-bean-factory-locator" properties-ref="gemfireProperties" use-bean-factory-locator="false"/>
<gfe:cache id="cache-with-use-cluster-configuration-disabled" use-cluster-configuration="false"/>
<gfe:cache id="cache-with-use-cluster-configuration-enabled" use-cluster-configuration="true"/>
<gfe:cache id="heap-tuned-cache" properties-ref="gemfireProperties" critical-heap-percentage="70.0" eviction-heap-percentage="60.0"/>
<gfe:cache id="off-heap-tuned-cache" properties-ref="gemfireProperties" critical-off-heap-percentage="90.0" eviction-off-heap-percentage="50.0"/>
<gfe:cache id="no-bean-factory-locator-cache" properties-ref="gemfireProperties" use-bean-factory-locator="false"/>
<gfe:client-cache id="client-cache-with-name"/>
<gfe:client-cache id="client-cache-with-xml" cache-xml-location="classpath:gemfire-client-cache.xml"/>

View File

@@ -23,11 +23,9 @@
<bean class="org.springframework.data.gemfire.test.GemfireTestBeanPostProcessor"/>
<util:properties id="gemfireProperties">
<prop key="log-level">warning</prop>
</util:properties>
<gfe:client-cache/>
<gfe:client-cache properties-ref="gemfireProperties"/>
<gfe:pool/>
<gfe:client-region id="simple" name="SimpleRegion"/>
@@ -81,9 +79,7 @@
shortcut="CACHING_PROXY"
value-constraint="java.lang.String"/>
<bean id="mockCache" class="org.springframework.data.gemfire.config.xml.ClientRegionNamespaceTest$MockCacheFactoryBean"/>
<gfe:client-region id="client-with-interests" ignore-if-exists="true" shortcut="PROXY" cache-ref="mockCache">
<gfe:client-region id="client-with-interests" ignore-if-exists="true" shortcut="PROXY">
<gfe:key-interest durable="${client.interests.durable}" receive-values="${client.interests.receive-values}"
result-policy="${client.key.interests.result-policy}">
<bean class="java.lang.String">
@@ -95,7 +91,6 @@
result-policy="${client.regex.interests.result-policy}"/>
</gfe:client-region>
<bean id="gemfire-pool" class="java.lang.Object" lazy-init="true"/>
<bean id="c-listener" class="org.springframework.data.gemfire.SimpleCacheListener"/>
<bean id="testCompressor" class="org.springframework.data.gemfire.config.xml.ClientRegionNamespaceTest$TestCompressor" p:name="STD"/>

View File

@@ -15,7 +15,8 @@
<util:properties id="gemfireProperties">
<prop key="name">ReplicatedNamespaceConfig</prop>
<prop key="mcast-port">0</prop>
<prop key="log-level">warning</prop>
<prop key="log-level">error</prop>
<prop key="off-heap-memory-size">64m</prop>
</util:properties>
<gfe:cache properties-ref="gemfireProperties"/>

View File

@@ -15,8 +15,7 @@
<util:properties id="gemfireProperties">
<prop key="name">RepositoryClientRegionIntegrationTestsServer</prop>
<prop key="mcast-port">0</prop>
<prop key="log-level">warning</prop>
<prop key="log-level">error</prop>
</util:properties>
<gfe:cache properties-ref="gemfireProperties"/>