SGF-672 - Use Geode's DEFAULT Pool when a Pool cannot be resolved from the Spring context.

This commit is contained in:
John Blum
2017-09-22 13:40:20 -07:00
parent d536c5763d
commit fd3d318d9e
36 changed files with 1247 additions and 620 deletions

View File

@@ -337,6 +337,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
* @see #findPool(String) * @see #findPool(String)
*/ */
Pool resolvePool() { Pool resolvePool() {
Pool localPool = getPool(); Pool localPool = getPool();
if (localPool == null) { if (localPool == null) {
@@ -411,6 +412,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
*/ */
@Override @Override
public void onApplicationEvent(ContextRefreshedEvent event) { public void onApplicationEvent(ContextRefreshedEvent event) {
if (isReadyForEvents()) { if (isReadyForEvents()) {
try { try {
this.<ClientCache>fetchCache().readyForEvents(); this.<ClientCache>fetchCache().readyForEvents();
@@ -772,6 +774,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
* @see #getReadyForEvents() * @see #getReadyForEvents()
*/ */
public boolean isReadyForEvents() { public boolean isReadyForEvents() {
Boolean readyForEvents = getReadyForEvents(); Boolean readyForEvents = getReadyForEvents();
if (readyForEvents != null) { if (readyForEvents != null) {

View File

@@ -40,6 +40,7 @@ import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientRegionFactory; import org.apache.geode.cache.client.ClientRegionFactory;
import org.apache.geode.cache.client.ClientRegionShortcut; import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.client.Pool; import org.apache.geode.cache.client.Pool;
import org.apache.geode.cache.client.PoolManager;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.FactoryBean;
@@ -75,6 +76,9 @@ import org.springframework.util.StringUtils;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> implements DisposableBean { public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> implements DisposableBean {
public static final String DEFAULT_POOL_NAME = "DEFAULT";
public static final String GEMFIRE_POOL_NAME = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME;
private boolean close = false; private boolean close = false;
private boolean destroy = false; private boolean destroy = false;
@@ -278,8 +282,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
} }
} }
else { else {
resolvedShortcut = (isPersistent() ? ClientRegionShortcut.LOCAL_PERSISTENT resolvedShortcut = (isPersistent() ? ClientRegionShortcut.LOCAL_PERSISTENT : ClientRegionShortcut.LOCAL);
: ClientRegionShortcut.LOCAL);
} }
} }
@@ -292,14 +295,17 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
/* (non-Javadoc) */ /* (non-Javadoc) */
private String resolvePoolName() { private String resolvePoolName() {
String poolName = this.poolName; return Optional.of(getPoolName()).filter(this::isPoolResolvable).orElse(null);
}
if (!StringUtils.hasText(poolName)) { /* (non-Javadoc) */
String defaultPoolName = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME; private String getPoolName() {
poolName = (getBeanFactory().containsBean(defaultPoolName) ? defaultPoolName : poolName); return Optional.ofNullable(this.poolName).filter(StringUtils::hasText).orElse(GEMFIRE_POOL_NAME);
} }
return poolName; /* (non-Javadoc) */
private boolean isPoolResolvable(String poolName) {
return (getBeanFactory().containsBean(poolName) || (PoolManager.find(poolName) != null));
} }
/* (non-Javadoc) */ /* (non-Javadoc) */
@@ -424,6 +430,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
private Region<K, V> registerInterests(Region<K, V> region) { private Region<K, V> registerInterests(Region<K, V> region) {
stream(nullSafeArray(this.interests, Interest.class)).forEach(interest -> { stream(nullSafeArray(this.interests, Interest.class)).forEach(interest -> {
if (interest.isRegexType()) { if (interest.isRegexType()) {
region.registerInterestRegex((String) interest.getKey(), interest.getPolicy(), region.registerInterestRegex((String) interest.getKey(), interest.getPolicy(),
interest.isDurable(), interest.isReceiveValues()); interest.isDurable(), interest.isReceiveValues());
@@ -447,6 +454,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
public void destroy() throws Exception { public void destroy() throws Exception {
Optional.ofNullable(getObject()).ifPresent(region -> { Optional.ofNullable(getObject()).ifPresent(region -> {
if (isClose()) { if (isClose()) {
if (!region.getRegionService().isClosed()) { if (!region.getRegionService().isClosed()) {
try { try {

View File

@@ -290,6 +290,7 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport<Pool> implements
protected PoolFactory configure(PoolFactory poolFactory) { protected PoolFactory configure(PoolFactory poolFactory) {
Optional.ofNullable(poolFactory).ifPresent(it -> { Optional.ofNullable(poolFactory).ifPresent(it -> {
it.setFreeConnectionTimeout(this.freeConnectionTimeout); it.setFreeConnectionTimeout(this.freeConnectionTimeout);
it.setIdleTimeout(this.idleTimeout); it.setIdleTimeout(this.idleTimeout);
it.setLoadConditioningInterval(this.loadConditioningInterval); it.setLoadConditioningInterval(this.loadConditioningInterval);
@@ -395,7 +396,9 @@ public class PoolFactoryBean extends AbstractFactoryBeanSupport<Pool> implements
/* (non-Javadoc) */ /* (non-Javadoc) */
public Pool getPool() { public Pool getPool() {
return Optional.ofNullable(this.pool).orElseGet(() -> new PoolAdapter() { return Optional.ofNullable(this.pool).orElseGet(() -> new PoolAdapter() {
@Override @Override
public boolean isDestroyed() { public boolean isDestroyed() {
Pool pool = PoolFactoryBean.this.pool; Pool pool = PoolFactoryBean.this.pool;

View File

@@ -25,10 +25,13 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import org.apache.geode.cache.Region; import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.Pool;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.AliasFor;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
import org.springframework.data.gemfire.mapping.annotation.ClientRegion;
/** /**
* The {@link EnableEntityDefinedRegions} annotation marks a Spring {@link Configuration @Configuration} application * The {@link EnableEntityDefinedRegions} annotation marks a Spring {@link Configuration @Configuration} application
@@ -46,6 +49,11 @@ import org.springframework.core.annotation.AliasFor;
* @see org.springframework.data.gemfire.config.annotation.EntityDefinedRegionsConfiguration * @see org.springframework.data.gemfire.config.annotation.EntityDefinedRegionsConfiguration
* @see org.springframework.data.gemfire.config.annotation.IndexConfiguration * @see org.springframework.data.gemfire.config.annotation.IndexConfiguration
* @see org.springframework.data.gemfire.config.annotation.support.GemFireCacheTypeAwareRegionFactoryBean * @see org.springframework.data.gemfire.config.annotation.support.GemFireCacheTypeAwareRegionFactoryBean
* @see org.springframework.data.gemfire.mapping.annotation.ClientRegion
* @see org.springframework.data.gemfire.mapping.annotation.LocalRegion
* @see org.springframework.data.gemfire.mapping.annotation.PartitionRegion
* @see org.springframework.data.gemfire.mapping.annotation.Region
* @see org.springframework.data.gemfire.mapping.annotation.ReplicateRegion
* @since 1.9.0 * @since 1.9.0
*/ */
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@@ -111,6 +119,16 @@ public @interface EnableEntityDefinedRegions {
*/ */
ComponentScan.Filter[] includeFilters() default {}; ComponentScan.Filter[] includeFilters() default {};
/**
* When this annotation is applied in a cache client application, the {@literal poolName} attribute refers to
* the default name of the GemFire/Geode {@link Pool} assigned to the client {@link Region Region(s)}.
*
* This value can be overridden by annotating entities with th e{@link ClientRegion} annotation.
*
* Defaults to {@literal DEFAULT}.
*/
String poolName() default ClientRegionFactoryBean.DEFAULT_POOL_NAME;
/** /**
* Determines whether the created {@link Region} will have strongly-typed key and value constraints * Determines whether the created {@link Region} will have strongly-typed key and value constraints
* based on the ID and {@link Class} type of application persistent entity. * based on the ID and {@link Class} type of application persistent entity.

View File

@@ -146,9 +146,9 @@ public @interface EnablePool {
/** /**
* Specifies the {@link String name} of the client {@link Pool} in Pivotal GemFire/Apache Geode, which is also * Specifies the {@link String name} of the client {@link Pool} in Pivotal GemFire/Apache Geode, which is also
* used as the Spring bean name in the container as well as the name * used as the name of the bean registered in the Spring container as well as the name used in the resolution
* (e.g. {@literal spring.data.gemfire.pool.<poolName>.max-connections} used in the resolution of {@link Pool} * of {@link Pool} properties from {@literal application.properties}
* properties from {@literal application.properties} that are specific to this {@link Pool}. * (e.g. {@literal spring.data.gemfire.pool.<poolName>.max-connections}), that are specific to this {@link Pool}.
*/ */
String name(); String name();

View File

@@ -22,6 +22,7 @@ import static org.springframework.data.gemfire.util.ArrayUtils.defaultIfEmpty;
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeMap; import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeMap;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
import static org.springframework.data.gemfire.util.SpringUtils.safeGetValue;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.util.Collections; import java.util.Collections;
@@ -37,10 +38,7 @@ import java.util.stream.Collectors;
import org.apache.geode.cache.Region; import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.ClientRegionShortcut; import org.apache.geode.cache.client.ClientRegionShortcut;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
@@ -50,7 +48,6 @@ import org.springframework.beans.factory.support.ManagedList;
import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AspectJTypeFilter; import org.springframework.core.type.filter.AspectJTypeFilter;
@@ -66,6 +63,7 @@ import org.springframework.data.gemfire.RegionLookupFactoryBean;
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean; import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
import org.springframework.data.gemfire.ScopeType; import org.springframework.data.gemfire.ScopeType;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean; import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport;
import org.springframework.data.gemfire.config.annotation.support.GemFireCacheTypeAwareRegionFactoryBean; import org.springframework.data.gemfire.config.annotation.support.GemFireCacheTypeAwareRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.GemFireComponentClassTypeScanner; import org.springframework.data.gemfire.config.annotation.support.GemFireComponentClassTypeScanner;
import org.springframework.data.gemfire.config.xml.GemfireConstants; import org.springframework.data.gemfire.config.xml.GemfireConstants;
@@ -76,7 +74,7 @@ import org.springframework.data.gemfire.mapping.annotation.ClientRegion;
import org.springframework.data.gemfire.mapping.annotation.LocalRegion; import org.springframework.data.gemfire.mapping.annotation.LocalRegion;
import org.springframework.data.gemfire.mapping.annotation.PartitionRegion; import org.springframework.data.gemfire.mapping.annotation.PartitionRegion;
import org.springframework.data.gemfire.mapping.annotation.ReplicateRegion; import org.springframework.data.gemfire.mapping.annotation.ReplicateRegion;
import org.springframework.data.gemfire.util.CollectionUtils; import org.springframework.data.gemfire.util.SpringUtils;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@@ -91,9 +89,6 @@ import org.springframework.util.StringUtils;
* @see java.lang.ClassLoader * @see java.lang.ClassLoader
* @see java.lang.annotation.Annotation * @see java.lang.annotation.Annotation
* @see org.apache.geode.cache.Region * @see org.apache.geode.cache.Region
* @see org.springframework.beans.factory.BeanClassLoaderAware
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.beans.factory.config.BeanDefinition * @see org.springframework.beans.factory.config.BeanDefinition
* @see org.springframework.beans.factory.support.BeanDefinitionBuilder * @see org.springframework.beans.factory.support.BeanDefinitionBuilder
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry * @see org.springframework.beans.factory.support.BeanDefinitionRegistry
@@ -116,8 +111,9 @@ import org.springframework.util.StringUtils;
* @see org.springframework.data.gemfire.mapping.annotation.Region * @see org.springframework.data.gemfire.mapping.annotation.Region
* @since 1.9.0 * @since 1.9.0
*/ */
public class EntityDefinedRegionsConfiguration @SuppressWarnings("unused")
implements BeanClassLoaderAware, BeanFactoryAware, ImportBeanDefinitionRegistrar { public class EntityDefinedRegionsConfiguration extends AbstractAnnotationConfigSupport
implements ImportBeanDefinitionRegistrar {
protected static final Class<? extends RegionLookupFactoryBean> DEFAULT_REGION_FACTORY_BEAN_CLASS = protected static final Class<? extends RegionLookupFactoryBean> DEFAULT_REGION_FACTORY_BEAN_CLASS =
GemFireCacheTypeAwareRegionFactoryBean.class; GemFireCacheTypeAwareRegionFactoryBean.class;
@@ -134,10 +130,6 @@ public class EntityDefinedRegionsConfiguration
DEFAULT_REGION_FACTORY_BEAN_CLASS); DEFAULT_REGION_FACTORY_BEAN_CLASS);
} }
private BeanFactory beanFactory;
private ClassLoader beanClassLoader;
private GemfireMappingContext mappingContext; private GemfireMappingContext mappingContext;
@Autowired(required = false) @Autowired(required = false)
@@ -153,112 +145,20 @@ public class EntityDefinedRegionsConfiguration
* @see java.lang.annotation.Annotation * @see java.lang.annotation.Annotation
* @see java.lang.Class * @see java.lang.Class
*/ */
@Override
protected Class<? extends Annotation> getAnnotationType() { protected Class<? extends Annotation> getAnnotationType() {
return EnableEntityDefinedRegions.class; return EnableEntityDefinedRegions.class;
} }
/** /**
* Returns the name of the {@link Annotation} type that configures and creates {@link Region Regions} * Registers {@link Region} bean definitions in the Spring context for all application domain object
* for application persistent entities. * that have been identified as {@link GemfirePersistentEntity persistent entities}.
* *
* @return the name of the {@link Annotation} type that configures and creates {@link Region Regions} * @param importingClassMetadata {@link Class} with the {@link EnableEntityDefinedRegions} annotation.
* for application persistent entities. * @param registry {@link BeanDefinitionRegistry} used to register the {@link Region} bean definitions
* @see java.lang.Class#getName() * in the Spring context.
* @see #getAnnotationType() * @see org.springframework.beans.factory.support.BeanDefinitionRegistry
*/ * @see org.springframework.core.type.AnnotationMetadata
protected String getAnnotationTypeName() {
return getAnnotationType().getName();
}
/**
* Returns the simple name of the {@link Annotation} type that configures and creates {@link Region Regions}
* for application persistent entities.
*
* @return the simple name of the {@link Annotation} type that configures and creates {@link Region Regions}
* for application persistent entities.
* @see java.lang.Class#getSimpleName()
* @see #getAnnotationType()
*/
@SuppressWarnings("unused")
protected String getAnnotationTypeSimpleName() {
return getAnnotationType().getSimpleName();
}
/**
* @inheritDoc
*/
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
/* (non-Javadoc) */
@SuppressWarnings("unused")
protected ClassLoader getBeanClassLoader() {
return this.beanClassLoader;
}
/**
* @inheritDoc
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
/* (non-Javadoc) */
protected BeanFactory getBeanFactory() {
return this.beanFactory;
}
/* (non-Javadoc) */
protected boolean isAnnotationPresent(AnnotationMetadata importingClassMetadata) {
return isAnnotationPresent(importingClassMetadata, getAnnotationTypeName());
}
/* (non-Javadoc) */
protected boolean isAnnotationPresent(AnnotationMetadata importingClassMetadata, String annotationName) {
return importingClassMetadata.hasAnnotation(annotationName);
}
/* (non-Javadoc) */
protected AnnotationAttributes getAnnotationAttributes(Annotation annotation) {
return AnnotationAttributes.fromMap(AnnotationUtils.getAnnotationAttributes(annotation));
}
/* (non-Javadoc) */
protected AnnotationAttributes getAnnotationAttributes(AnnotationMetadata importingClassMetadata) {
return getAnnotationAttributes(importingClassMetadata, getAnnotationTypeName());
}
/* (non-Javadoc) */
protected AnnotationAttributes getAnnotationAttributes(AnnotationMetadata importingClassMetadata,
String annotationName) {
return AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(annotationName));
}
/* (non-Javadoc) */
protected GemfirePersistentEntity<?> getPersistentEntity(Class<?> persistentEntityType) {
return resolveMappingContext().getPersistentEntity(persistentEntityType);
}
/* (non-Javadoc) */
protected GemfireMappingContext resolveMappingContext() {
return Optional.ofNullable(this.mappingContext).orElseGet(() -> {
try {
this.mappingContext = getBeanFactory().getBean(GemfireMappingContext.class);
}
catch (Throwable ignore) {
this.mappingContext = new GemfireMappingContext();
}
return this.mappingContext;
});
}
/**
* @inheritDoc
*/ */
@Override @Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
@@ -267,6 +167,8 @@ public class EntityDefinedRegionsConfiguration
AnnotationAttributes enableEntityDefinedRegionsAttributes = getAnnotationAttributes(importingClassMetadata); AnnotationAttributes enableEntityDefinedRegionsAttributes = getAnnotationAttributes(importingClassMetadata);
String poolName = enableEntityDefinedRegionsAttributes.getString("poolName");
boolean strict = enableEntityDefinedRegionsAttributes.getBoolean("strict"); boolean strict = enableEntityDefinedRegionsAttributes.getBoolean("strict");
newGemFireComponentClassTypeScanner(importingClassMetadata, enableEntityDefinedRegionsAttributes).scan() newGemFireComponentClassTypeScanner(importingClassMetadata, enableEntityDefinedRegionsAttributes).scan()
@@ -274,7 +176,7 @@ public class EntityDefinedRegionsConfiguration
GemfirePersistentEntity persistentEntity = getPersistentEntity(persistentEntityClass); GemfirePersistentEntity persistentEntity = getPersistentEntity(persistentEntityClass);
registerRegionBeanDefinition(persistentEntity, strict, registry); registerRegionBeanDefinition(persistentEntity, poolName, strict, registry);
postProcess(importingClassMetadata, registry, persistentEntity); postProcess(importingClassMetadata, registry, persistentEntity);
}); });
} }
@@ -290,7 +192,7 @@ public class EntityDefinedRegionsConfiguration
return GemFireComponentClassTypeScanner.from(resolvedBasePackages).with(resolveBeanClassLoader()) return GemFireComponentClassTypeScanner.from(resolvedBasePackages).with(resolveBeanClassLoader())
.withExcludes(resolveExcludes(enableEntityDefinedRegionsAttributes)) .withExcludes(resolveExcludes(enableEntityDefinedRegionsAttributes))
.withIncludes(resolveIncludes(enableEntityDefinedRegionsAttributes)) .withIncludes(resolveIncludes(enableEntityDefinedRegionsAttributes))
.withIncludes(regionAnnotatedPersistentEntityTypeFilters()); .withIncludes(resolveRegionAnnotatedPersistentEntityTypeFilters());
} }
/* (non-Javadoc) */ /* (non-Javadoc) */
@@ -315,12 +217,6 @@ public class EntityDefinedRegionsConfiguration
return resolvedBasePackages; return resolvedBasePackages;
} }
/* (non-Javadoc) */
protected ClassLoader resolveBeanClassLoader() {
return Optional.ofNullable(this.beanClassLoader)
.orElseGet(() -> Thread.currentThread().getContextClassLoader());
}
/* (non-Javadoc) */ /* (non-Javadoc) */
protected Iterable<TypeFilter> resolveExcludes(AnnotationAttributes enableEntityDefinedRegionsAttributes) { protected Iterable<TypeFilter> resolveExcludes(AnnotationAttributes enableEntityDefinedRegionsAttributes) {
return parseFilters(enableEntityDefinedRegionsAttributes.getAnnotationArray("excludeFilters")); return parseFilters(enableEntityDefinedRegionsAttributes.getAnnotationArray("excludeFilters"));
@@ -332,25 +228,31 @@ public class EntityDefinedRegionsConfiguration
} }
/* (non-Javadoc) */ /* (non-Javadoc) */
private Iterable<TypeFilter> parseFilters(AnnotationAttributes[] componentScanFilterAttributes) { @SuppressWarnings("unchecked")
protected Iterable<TypeFilter> resolveRegionAnnotatedPersistentEntityTypeFilters() {
Set<TypeFilter> typeFilters = new HashSet<>(); return org.springframework.data.gemfire.mapping.annotation.Region.REGION_ANNOTATION_TYPES.stream()
.map(AnnotationTypeFilter::new)
stream(nullSafeArray(componentScanFilterAttributes, AnnotationAttributes.class)) .collect(Collectors.toSet());
.forEach(filterAttributes -> CollectionUtils.addAll(typeFilters, typeFiltersFor(filterAttributes))); }
return typeFilters; private Iterable<TypeFilter> parseFilters(AnnotationAttributes[] componentScanFilterAttributes) {
return stream(nullSafeArray(componentScanFilterAttributes, AnnotationAttributes.class))
.flatMap(filterAttributes -> typeFiltersFor(filterAttributes).stream())
.collect(Collectors.toSet());
} }
/* (non-Javadoc) */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Iterable<TypeFilter> typeFiltersFor(AnnotationAttributes filterAttributes) { private Set<TypeFilter> typeFiltersFor(AnnotationAttributes filterAttributes) {
Set<TypeFilter> typeFilters = new HashSet<>(); Set<TypeFilter> typeFilters = new HashSet<>();
FilterType filterType = filterAttributes.getEnum("type"); FilterType filterType = filterAttributes.getEnum("type");
stream(nullSafeArray(filterAttributes.getClassArray("value"), Class.class)) stream(nullSafeArray(filterAttributes.getClassArray("value"), Class.class))
.forEach(filterClass -> { .forEach(filterClass -> {
switch (filterType) { switch (filterType) {
case ANNOTATION: case ANNOTATION:
Assert.isAssignable(Annotation.class, filterClass, Assert.isAssignable(Annotation.class, filterClass,
@@ -383,7 +285,7 @@ public class EntityDefinedRegionsConfiguration
"Illegal filter type [%s] when 'patterns' are specified", filterType); "Illegal filter type [%s] when 'patterns' are specified", filterType);
} }
} }
}); });
return typeFilters; return typeFilters;
} }
@@ -396,29 +298,61 @@ public class EntityDefinedRegionsConfiguration
* @return a {@link String} array. * @return a {@link String} array.
*/ */
private String[] nullSafeGetPatterns(AnnotationAttributes filterAttributes) { private String[] nullSafeGetPatterns(AnnotationAttributes filterAttributes) {
try {
return nullSafeArray(filterAttributes.getStringArray("pattern"), String.class); return SpringUtils.<String[]>safeGetValue(() ->
} nullSafeArray(filterAttributes.getStringArray("pattern"), String.class), () -> new String[0]);
catch (IllegalArgumentException ignore) {
return new String[0];
}
} }
/* (non-Javadoc) */ /**
@SuppressWarnings("unchecked") * Returns the associated {@link GemfirePersistentEntity persistent entity} for the given application
protected Iterable<TypeFilter> regionAnnotatedPersistentEntityTypeFilters() { * domain object type.
*
Set<TypeFilter> regionAnnotatedPersistentEntityTypeFilters = new HashSet<>(); * @param persistentEntityType {@link Class type} of the application domain object used to lookup
* the {@link GemfirePersistentEntity persistent entity} from the {@link @GemfireMappingContext mapping context}.
org.springframework.data.gemfire.mapping.annotation.Region.REGION_ANNOTATION_TYPES.forEach( * @return the {@link GemfirePersistentEntity persistent entity} for the given application domain object type.
annotationType -> regionAnnotatedPersistentEntityTypeFilters.add(new AnnotationTypeFilter(annotationType))); * @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity
* @see java.lang.Class
return regionAnnotatedPersistentEntityTypeFilters; */
protected GemfirePersistentEntity<?> getPersistentEntity(Class<?> persistentEntityType) {
return resolveMappingContext().getPersistentEntity(persistentEntityType);
} }
/* (non-Javadoc) */ /**
protected void registerRegionBeanDefinition(GemfirePersistentEntity persistentEntity, boolean strict, * Resolves the {@link GemfireMappingContext mapping context} by returning the configured
BeanDefinitionRegistry registry) { * {@link GemfireMappingContext mapping context} if present, or attempts to lookup
* the {@link GemfireMappingContext mapping context} from the configured {@link BeanFactory}.
* If the lookup is unsuccessful, then this method will return a new {@link GemfireMappingContext mapping context}.
*
* @return the resolved {@link GemfireMappingContext mapping context}.
* @see org.springframework.data.gemfire.mapping.GemfireMappingContext
*/
protected GemfireMappingContext resolveMappingContext() {
return Optional.ofNullable(this.mappingContext).orElseGet(() -> {
try {
this.mappingContext = beanFactory().getBean(GemfireMappingContext.class);
}
catch (Throwable ignore) {
this.mappingContext = new GemfireMappingContext();
}
return this.mappingContext;
});
}
/**
* Registers an individual bean definition in the Spring container for the {@link Region} determined from
* the application domain object, {@link GemfirePersistentEntity persistent entity}.
*
* @param persistentEntity {@link GemfirePersistentEntity} from which to the resolve the {@link Region}.
* @param strict boolean value indicating whether the key and value constraints on the {@link Region} should be set.
* @param registry {@link BeanDefinitionRegistry} used to register the {@link Region} bean definition
* in the Spring context.
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
* @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity
*/
protected void registerRegionBeanDefinition(GemfirePersistentEntity persistentEntity, String poolName,
boolean strict, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder regionFactoryBeanBuilder = BeanDefinitionBuilder regionFactoryBeanBuilder =
BeanDefinitionBuilder.genericBeanDefinition(resolveRegionFactoryBeanClass(persistentEntity)) BeanDefinitionBuilder.genericBeanDefinition(resolveRegionFactoryBeanClass(persistentEntity))
@@ -426,19 +360,29 @@ public class EntityDefinedRegionsConfiguration
.addPropertyValue("regionConfigurers", resolveRegionConfigurers()) .addPropertyValue("regionConfigurers", resolveRegionConfigurers())
.addPropertyValue("close", false); .addPropertyValue("close", false);
setRegionAttributes(persistentEntity, regionFactoryBeanBuilder, strict); setRegionAttributes(persistentEntity, regionFactoryBeanBuilder, poolName, strict);
registry.registerBeanDefinition(persistentEntity.getRegionName(), registry.registerBeanDefinition(persistentEntity.getRegionName(),
regionFactoryBeanBuilder.getBeanDefinition()); regionFactoryBeanBuilder.getBeanDefinition());
} }
/* (non-Javadoc) */ /* (non-Javadoc) */
private List<RegionConfigurer> resolveRegionConfigurers() { @SuppressWarnings("unchecked")
protected Class<? extends RegionLookupFactoryBean> resolveRegionFactoryBeanClass(
GemfirePersistentEntity persistentEntity) {
return Optional.<Class<? extends RegionLookupFactoryBean>>ofNullable(
regionAnnotationToRegionFactoryBeanClass.get(persistentEntity.getRegionAnnotationType()))
.orElse(DEFAULT_REGION_FACTORY_BEAN_CLASS);
}
/* (non-Javadoc) */
protected List<RegionConfigurer> resolveRegionConfigurers() {
return Optional.ofNullable(this.regionConfigurers) return Optional.ofNullable(this.regionConfigurers)
.filter(regionConfigurers -> !regionConfigurers.isEmpty()) .filter(regionConfigurers -> !regionConfigurers.isEmpty())
.orElseGet(() -> .orElseGet(() ->
Optional.ofNullable(this.beanFactory) Optional.ofNullable(beanFactory())
.filter(beanFactory -> beanFactory instanceof ListableBeanFactory) .filter(beanFactory -> beanFactory instanceof ListableBeanFactory)
.map(beanFactory -> { .map(beanFactory -> {
Map<String, RegionConfigurer> beansOfType = ((ListableBeanFactory) beanFactory) Map<String, RegionConfigurer> beansOfType = ((ListableBeanFactory) beanFactory)
@@ -450,21 +394,12 @@ public class EntityDefinedRegionsConfiguration
); );
} }
/* (non-Javadoc) */
@SuppressWarnings("unchecked")
protected Class<? extends RegionLookupFactoryBean> resolveRegionFactoryBeanClass(
GemfirePersistentEntity persistentEntity) {
return Optional.<Class<? extends RegionLookupFactoryBean>>ofNullable(
regionAnnotationToRegionFactoryBeanClass.get(persistentEntity.getRegionAnnotationType()))
.orElse(DEFAULT_REGION_FACTORY_BEAN_CLASS);
}
/* (non-Javadoc) */ /* (non-Javadoc) */
protected BeanDefinitionBuilder setRegionAttributes(GemfirePersistentEntity persistentEntity, protected BeanDefinitionBuilder setRegionAttributes(GemfirePersistentEntity persistentEntity,
BeanDefinitionBuilder regionFactoryBeanBuilder, boolean strict) { BeanDefinitionBuilder regionFactoryBeanBuilder, String poolName, boolean strict) {
Optional.ofNullable(persistentEntity.getRegionAnnotation()).ifPresent(regionAnnotation -> { Optional.ofNullable(persistentEntity.getRegionAnnotation()).ifPresent(regionAnnotation -> {
AnnotationAttributes regionAnnotationAttributes = getAnnotationAttributes(regionAnnotation); AnnotationAttributes regionAnnotationAttributes = getAnnotationAttributes(regionAnnotation);
if (strict) { if (strict) {
@@ -473,10 +408,11 @@ public class EntityDefinedRegionsConfiguration
} }
if (regionAnnotationAttributes.containsKey("diskStoreName")) { if (regionAnnotationAttributes.containsKey("diskStoreName")) {
String diskStoreName = regionAnnotationAttributes.getString("diskStoreName"); String diskStoreName = regionAnnotationAttributes.getString("diskStoreName");
setPropertyValueIfNotDefault(regionFactoryBeanBuilder, "diskStoreName", setPropertyValueIfNotDefault(regionFactoryBeanBuilder, "diskStoreName", diskStoreName,
diskStoreName, ""); "");
if (StringUtils.hasText(diskStoreName)) { if (StringUtils.hasText(diskStoreName)) {
regionFactoryBeanBuilder.addDependsOn(diskStoreName); regionFactoryBeanBuilder.addDependsOn(diskStoreName);
@@ -506,7 +442,7 @@ public class EntityDefinedRegionsConfiguration
regionAnnotationAttributes.getBoolean("ignoreJta"), false); regionAnnotationAttributes.getBoolean("ignoreJta"), false);
} }
setClientRegionAttributes(regionAnnotationAttributes, regionFactoryBeanBuilder); setClientRegionAttributes(regionAnnotationAttributes, poolName, regionFactoryBeanBuilder);
setPartitionRegionAttributes(regionAnnotationAttributes, regionFactoryBeanBuilder, setPartitionRegionAttributes(regionAnnotationAttributes, regionFactoryBeanBuilder,
regionAttributesFactoryBeanBuilder); regionAttributesFactoryBeanBuilder);
@@ -519,7 +455,7 @@ public class EntityDefinedRegionsConfiguration
/* (non-Javadoc) */ /* (non-Javadoc) */
protected Class<?> resolveDomainType(GemfirePersistentEntity persistentEntity) { protected Class<?> resolveDomainType(GemfirePersistentEntity persistentEntity) {
return Optional.ofNullable(persistentEntity.getType()).orElse(Object.class); return persistentEntity.getType();
} }
/* (non-Javadoc) */ /* (non-Javadoc) */
@@ -550,9 +486,9 @@ public class EntityDefinedRegionsConfiguration
/* (non-Javadoc) */ /* (non-Javadoc) */
protected BeanDefinitionBuilder setClientRegionAttributes(AnnotationAttributes regionAnnotationAttributes, protected BeanDefinitionBuilder setClientRegionAttributes(AnnotationAttributes regionAnnotationAttributes,
BeanDefinitionBuilder regionFactoryBeanBuilder) { String poolName, BeanDefinitionBuilder regionFactoryBeanBuilder) {
if (regionAnnotationAttributes.containsKey("poolName")) { if (isPoolNameConfigured(regionAnnotationAttributes, poolName)) {
setPropertyValueIfNotDefault(regionFactoryBeanBuilder, "poolName", setPropertyValueIfNotDefault(regionFactoryBeanBuilder, "poolName",
regionAnnotationAttributes.getString("poolName"), null); regionAnnotationAttributes.getString("poolName"), null);
} }
@@ -565,6 +501,15 @@ public class EntityDefinedRegionsConfiguration
return regionFactoryBeanBuilder; return regionFactoryBeanBuilder;
} }
private boolean isPoolNameConfigured(AnnotationAttributes regionAnnotationAttributes, String poolName) {
return (regionAnnotationAttributes.containsKey("poolName")
|| !ClientRegionFactoryBean.DEFAULT_POOL_NAME.equals(poolName));
}
private String resolvePoolName(AnnotationAttributes regionAnnotationAttributes, String poolName) {
return safeGetValue(() -> regionAnnotationAttributes.getString("poolName"), poolName);
}
/* (non-Javadoc) */ /* (non-Javadoc) */
protected BeanDefinitionBuilder setPartitionRegionAttributes(AnnotationAttributes regionAnnotationAttributes, protected BeanDefinitionBuilder setPartitionRegionAttributes(AnnotationAttributes regionAnnotationAttributes,
BeanDefinitionBuilder regionFactoryBeanBuilder, BeanDefinitionBuilder regionAttributesFactoryBeanBuilder) { BeanDefinitionBuilder regionFactoryBeanBuilder, BeanDefinitionBuilder regionAttributesFactoryBeanBuilder) {

View File

@@ -276,7 +276,7 @@ public class IndexConfiguration extends EntityDefinedRegionsConfiguration {
return Optional.ofNullable(this.indexConfigurers) return Optional.ofNullable(this.indexConfigurers)
.filter(indexConfigurers -> !indexConfigurers.isEmpty()) .filter(indexConfigurers -> !indexConfigurers.isEmpty())
.orElseGet(() -> .orElseGet(() ->
Optional.of(getBeanFactory()) Optional.of(beanFactory())
.filter(beanFactory -> beanFactory instanceof ListableBeanFactory) .filter(beanFactory -> beanFactory instanceof ListableBeanFactory)
.map(beanFactory -> { .map(beanFactory -> {
Map<String, IndexConfigurer> beansOfType = ((ListableBeanFactory) beanFactory) Map<String, IndexConfigurer> beansOfType = ((ListableBeanFactory) beanFactory)

View File

@@ -20,6 +20,7 @@ package org.springframework.data.gemfire.config.annotation.support;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException; import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
import java.lang.annotation.Annotation;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -40,7 +41,10 @@ import org.springframework.context.EnvironmentAware;
import org.springframework.context.expression.BeanFactoryAccessor; import org.springframework.context.expression.BeanFactoryAccessor;
import org.springframework.context.expression.EnvironmentAccessor; import org.springframework.context.expression.EnvironmentAccessor;
import org.springframework.context.expression.MapAccessor; import org.springframework.context.expression.MapAccessor;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.expression.EvaluationContext; import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter; import org.springframework.expression.spel.support.StandardTypeConverter;
@@ -186,12 +190,39 @@ public abstract class AbstractAnnotationConfigSupport
return LogFactory.getLog(getClass()); return LogFactory.getLog(getClass());
} }
/* (non-Javadoc) */
protected boolean isAnnotationPresent(AnnotationMetadata importingClassMetadata) {
return isAnnotationPresent(importingClassMetadata, getAnnotationTypeName());
}
/* (non-Javadoc) */
protected boolean isAnnotationPresent(AnnotationMetadata importingClassMetadata, String annotationName) {
return importingClassMetadata.hasAnnotation(annotationName);
}
/* (non-Javadoc) */
protected AnnotationAttributes getAnnotationAttributes(Annotation annotation) {
return AnnotationAttributes.fromMap(AnnotationUtils.getAnnotationAttributes(annotation));
}
/* (non-Javadoc) */
protected AnnotationAttributes getAnnotationAttributes(AnnotationMetadata importingClassMetadata) {
return getAnnotationAttributes(importingClassMetadata, getAnnotationTypeName());
}
/* (non-Javadoc) */
protected AnnotationAttributes getAnnotationAttributes(AnnotationMetadata importingClassMetadata,
String annotationName) {
return AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(annotationName));
}
/** /**
* Returns the cache application {@link java.lang.annotation.Annotation} type pertaining to this configuration. * Returns the cache application {@link java.lang.annotation.Annotation} type pertaining to this configuration.
* *
* @return the cache application {@link java.lang.annotation.Annotation} type used by this application. * @return the cache application {@link java.lang.annotation.Annotation} type used by this application.
*/ */
protected abstract Class getAnnotationType(); protected abstract Class<? extends Annotation> getAnnotationType();
/** /**
* Returns the fully-qualified {@link Class#getName() class name} of the cache application * Returns the fully-qualified {@link Class#getName() class name} of the cache application
@@ -238,6 +269,19 @@ public abstract class AbstractAnnotationConfigSupport
return this.beanClassLoader; return this.beanClassLoader;
} }
/**
* Resolves the {@link ClassLoader bean ClassLoader} to the configured {@link ClassLoader}
* or the {@link Thread#getContextClassLoader() Thread Context ClassLoader}.
*
* @return the configured {@link ClassLoader} or the
* {@link Thread#getContextClassLoader() Thread Context ClassLoader}.
* @see java.lang.Thread#getContextClassLoader()
* @see #beanClassLoader()
*/
protected ClassLoader resolveBeanClassLoader() {
return Optional.ofNullable(beanClassLoader()).orElseGet(() -> Thread.currentThread().getContextClassLoader());
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@@ -282,8 +326,10 @@ public abstract class AbstractAnnotationConfigSupport
} }
/** /**
* Returns a reference to the {@link EvaluationContext} used to evaluate SpEL expressions.
* *
* @return * @return a reference to the {@link EvaluationContext} used to evaluate SpEL expressions.
* @see org.springframework.expression.EvaluationContext
*/ */
protected EvaluationContext evaluationContext() { protected EvaluationContext evaluationContext() {
return this.evaluationContext; return this.evaluationContext;

View File

@@ -132,11 +132,6 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota
return !CollectionUtils.isEmpty(properties); return !CollectionUtils.isEmpty(properties);
} }
/* (non-Javadoc) */
protected Map<String, Object> getAnnotationAttributes(AnnotationMetadata importingClassMetadata) {
return importingClassMetadata.getAnnotationAttributes(getAnnotationTypeName());
}
/* (non-Javadoc) */ /* (non-Javadoc) */
protected void registerGemFirePropertiesBeanPostProcessor(BeanDefinitionRegistry registry, protected void registerGemFirePropertiesBeanPostProcessor(BeanDefinitionRegistry registry,
Properties customGemFireProperties) { Properties customGemFireProperties) {

View File

@@ -30,13 +30,13 @@ import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes; import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.RegionShortcut; import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.client.ClientRegionShortcut; import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.client.PoolManager;
import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.FactoryBean;
import org.springframework.data.gemfire.GemfireUtils; import org.springframework.data.gemfire.GemfireUtils;
import org.springframework.data.gemfire.GenericRegionFactoryBean; import org.springframework.data.gemfire.GenericRegionFactoryBean;
import org.springframework.data.gemfire.RegionLookupFactoryBean; import org.springframework.data.gemfire.RegionLookupFactoryBean;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean; import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.RegionConfigurer; import org.springframework.data.gemfire.config.annotation.RegionConfigurer;
import org.springframework.data.gemfire.config.xml.GemfireConstants;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@@ -47,7 +47,6 @@ import org.springframework.util.StringUtils;
* @author John Blum * @author John Blum
* @see org.apache.geode.cache.GemFireCache * @see org.apache.geode.cache.GemFireCache
* @see org.apache.geode.cache.Region * @see org.apache.geode.cache.Region
* @see org.springframework.beans.factory.FactoryBean
* @see org.springframework.data.gemfire.GenericRegionFactoryBean * @see org.springframework.data.gemfire.GenericRegionFactoryBean
* @see org.springframework.data.gemfire.RegionLookupFactoryBean * @see org.springframework.data.gemfire.RegionLookupFactoryBean
* @see org.springframework.data.gemfire.RegionFactoryBean * @see org.springframework.data.gemfire.RegionFactoryBean
@@ -109,12 +108,13 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
clientRegionFactory.setCache(gemfireCache); clientRegionFactory.setCache(gemfireCache);
clientRegionFactory.setClose(isClose()); clientRegionFactory.setClose(isClose());
clientRegionFactory.setKeyConstraint(getKeyConstraint()); clientRegionFactory.setKeyConstraint(getKeyConstraint());
clientRegionFactory.setPoolName(getPoolName());
clientRegionFactory.setRegionConfigurers(this.regionConfigurers); clientRegionFactory.setRegionConfigurers(this.regionConfigurers);
clientRegionFactory.setRegionName(regionName); clientRegionFactory.setRegionName(regionName);
clientRegionFactory.setShortcut(getClientRegionShortcut()); clientRegionFactory.setShortcut(getClientRegionShortcut());
clientRegionFactory.setValueConstraint(getValueConstraint()); clientRegionFactory.setValueConstraint(getValueConstraint());
resolvePoolName().ifPresent(clientRegionFactory::setPoolName);
clientRegionFactory.afterPropertiesSet(); clientRegionFactory.afterPropertiesSet();
return clientRegionFactory.getObject(); return clientRegionFactory.getObject();
@@ -137,6 +137,7 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
GenericRegionFactoryBean<K, V> serverRegionFactory = new GenericRegionFactoryBean<>(); GenericRegionFactoryBean<K, V> serverRegionFactory = new GenericRegionFactoryBean<>();
serverRegionFactory.setAttributes(getRegionAttributes()); serverRegionFactory.setAttributes(getRegionAttributes());
serverRegionFactory.setBeanFactory(getBeanFactory());
serverRegionFactory.setCache(gemfireCache); serverRegionFactory.setCache(gemfireCache);
serverRegionFactory.setClose(isClose()); serverRegionFactory.setClose(isClose());
serverRegionFactory.setDataPolicy(getDataPolicy()); serverRegionFactory.setDataPolicy(getDataPolicy());
@@ -201,7 +202,15 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
protected String getPoolName() { protected String getPoolName() {
return Optional.ofNullable(this.poolName).filter(StringUtils::hasText) return Optional.ofNullable(this.poolName).filter(StringUtils::hasText)
.orElse(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME); .orElse(ClientRegionFactoryBean.GEMFIRE_POOL_NAME);
}
protected Optional<String> resolvePoolName() {
return Optional.of(getPoolName()).filter(this::isPoolResolvable);
}
private boolean isPoolResolvable(String poolName) {
return (getBeanFactory().containsBean(poolName) || (PoolManager.find(poolName) != null));
} }
/** /**

View File

@@ -17,23 +17,29 @@
package org.springframework.data.gemfire.config.annotation.support; package org.springframework.data.gemfire.config.annotation.support;
import static java.util.stream.StreamSupport.stream;
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
import static org.springframework.data.gemfire.util.CollectionUtils.asSet;
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeIterable;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.core.env.StandardEnvironment; import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.type.filter.TypeFilter; import org.springframework.core.type.filter.TypeFilter;
import org.springframework.data.gemfire.util.ArrayUtils;
import org.springframework.data.gemfire.util.CollectionUtils;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/** /**
* The {@link GemFireComponentClassTypeScanner} class is a classpath component scanner used to search * The {@link GemFireComponentClassTypeScanner} class is a classpath component scanner used to search
@@ -44,6 +50,7 @@ import org.springframework.util.ClassUtils;
* @see org.springframework.context.ConfigurableApplicationContext * @see org.springframework.context.ConfigurableApplicationContext
* @see org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider * @see org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider
* @see org.springframework.core.env.Environment * @see org.springframework.core.env.Environment
* @see org.springframework.core.type.filter.TypeFilter
* @since 1.9.0 * @since 1.9.0
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
@@ -59,8 +66,7 @@ public class GemFireComponentClassTypeScanner implements Iterable<String> {
* @see #GemFireComponentClassTypeScanner(Set) * @see #GemFireComponentClassTypeScanner(Set)
*/ */
public static GemFireComponentClassTypeScanner from(String... basePackages) { public static GemFireComponentClassTypeScanner from(String... basePackages) {
return new GemFireComponentClassTypeScanner(CollectionUtils.asSet( return new GemFireComponentClassTypeScanner(asSet(nullSafeArray(basePackages, String.class)));
ArrayUtils.nullSafeArray(basePackages, String.class)));
} }
/** /**
@@ -73,21 +79,16 @@ public class GemFireComponentClassTypeScanner implements Iterable<String> {
* @see #GemFireComponentClassTypeScanner(Set) * @see #GemFireComponentClassTypeScanner(Set)
*/ */
public static GemFireComponentClassTypeScanner from(Iterable<String> basePackages) { public static GemFireComponentClassTypeScanner from(Iterable<String> basePackages) {
Set<String> basePackageSet = new HashSet<String>(); return new GemFireComponentClassTypeScanner(stream(basePackages.spliterator(), false)
.collect(Collectors.toSet()));
for (String basePackage : CollectionUtils.nullSafeIterable(basePackages)) {
basePackageSet.add(basePackage);
}
return new GemFireComponentClassTypeScanner(basePackageSet);
} }
private ClassLoader entityClassLoader; private ClassLoader entityClassLoader;
private ConfigurableApplicationContext applicationContext; private ConfigurableApplicationContext applicationContext;
private Set<TypeFilter> excludes = new HashSet<TypeFilter>(); private Set<TypeFilter> excludes = new HashSet<>();
private Set<TypeFilter> includes = new HashSet<TypeFilter>(); private Set<TypeFilter> includes = new HashSet<>();
protected final Log log = LogFactory.getLog(getClass()); protected final Log log = LogFactory.getLog(getClass());
@@ -102,7 +103,7 @@ public class GemFireComponentClassTypeScanner implements Iterable<String> {
* @see java.util.Set * @see java.util.Set
*/ */
protected GemFireComponentClassTypeScanner(Set<String> basePackages) { protected GemFireComponentClassTypeScanner(Set<String> basePackages) {
Assert.notEmpty(basePackages, "Base packages must be specified"); Assert.notEmpty(basePackages, "Base packages is required");
this.basePackages = basePackages; this.basePackages = basePackages;
} }
@@ -120,21 +121,24 @@ public class GemFireComponentClassTypeScanner implements Iterable<String> {
* Returns an unmodifiable {@link Set} of base packages to scan for GemFire components. * Returns an unmodifiable {@link Set} of base packages to scan for GemFire components.
* *
* @return an unmodifiable {@link Set} of base packages to scan for GemFire components. * @return an unmodifiable {@link Set} of base packages to scan for GemFire components.
* @see java.util.Set
*/ */
protected Set<String> getBasePackages() { protected Set<String> getBasePackages() {
return Collections.unmodifiableSet(this.basePackages); return Collections.unmodifiableSet(this.basePackages);
} }
/** /**
* Returns a reference to the {@link ClassLoader} to find and load GemFire application persistent entity classes. * Returns a reference to the {@link ClassLoader} used to find and load GemFire application
* persistent entity classes.
* *
* @return a {@link ClassLoader} to find and load GemFire application persistent entity classes. * @return the {@link ClassLoader} used to find and load GemFire application persistent entity classes.
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#getBeanClassLoader() * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#getBeanClassLoader()
* @see java.lang.Thread#getContextClassLoader() * @see java.lang.Thread#getContextClassLoader()
* @see java.lang.ClassLoader * @see java.lang.ClassLoader
* @see #getApplicationContext() * @see #getApplicationContext()
*/ */
protected ClassLoader getEntityClassLoader() { protected ClassLoader getEntityClassLoader() {
ConfigurableApplicationContext applicationContext = getApplicationContext(); ConfigurableApplicationContext applicationContext = getApplicationContext();
return (this.entityClassLoader != null ? this.entityClassLoader return (this.entityClassLoader != null ? this.entityClassLoader
@@ -152,8 +156,10 @@ public class GemFireComponentClassTypeScanner implements Iterable<String> {
* @see #getApplicationContext() * @see #getApplicationContext()
*/ */
protected Environment getEnvironment() { protected Environment getEnvironment() {
ConfigurableApplicationContext applicationContext = getApplicationContext();
return (applicationContext != null ? applicationContext.getEnvironment() : new StandardEnvironment()); return Optional.ofNullable(getApplicationContext())
.map(ConfigurableApplicationContext::getEnvironment)
.orElse(new StandardEnvironment());
} }
/** /**
@@ -162,6 +168,7 @@ public class GemFireComponentClassTypeScanner implements Iterable<String> {
* *
* @return a collection of {@link TypeFilter} objects * @return a collection of {@link TypeFilter} objects
* @see org.springframework.core.type.filter.TypeFilter * @see org.springframework.core.type.filter.TypeFilter
* @see java.lang.Iterable
*/ */
protected Iterable<TypeFilter> getExcludes() { protected Iterable<TypeFilter> getExcludes() {
return this.excludes; return this.excludes;
@@ -173,46 +180,49 @@ public class GemFireComponentClassTypeScanner implements Iterable<String> {
* *
* @return a collection of {@link TypeFilter} objects * @return a collection of {@link TypeFilter} objects
* @see org.springframework.core.type.filter.TypeFilter * @see org.springframework.core.type.filter.TypeFilter
* @see java.lang.Iterable
*/ */
protected Iterable<TypeFilter> getIncludes() { protected Iterable<TypeFilter> getIncludes() {
return this.includes; return this.includes;
} }
/**
* @inheritDoc
*/
@Override @Override
public Iterator<String> iterator() { public Iterator<String> iterator() {
return getBasePackages().iterator(); return getBasePackages().iterator();
} }
/** /**
* Scans the {@link Set} of base packages searching for GemFire application components accepted by the filters * Scans the {@link Set} of base packages searching for GemFire application components
* of this scanner. * accepted by the filters of this scanner.
* *
* @return a {@link Set} of GemFire application component {@link Class} types. * @return a {@link Set} of GemFire application component {@link Class} types found on the classpath.
* @see #newClassPathScanningCandidateComponentProvider(boolean) * @see #newClassPathScanningCandidateComponentProvider(boolean)
* @see java.util.Set * @see java.util.Set
*/ */
public Set<Class<?>> scan() { public Set<Class<?>> scan() {
Set<Class<?>> componentClasses = new HashSet<Class<?>>();
Set<Class<?>> componentClasses = new CopyOnWriteArraySet<>();
ClassLoader entityClassLoader = getEntityClassLoader(); ClassLoader entityClassLoader = getEntityClassLoader();
ClassPathScanningCandidateComponentProvider componentProvider = ClassPathScanningCandidateComponentProvider componentProvider =
newClassPathScanningCandidateComponentProvider(); newClassPathScanningCandidateComponentProvider();
for (String packageName : this) { stream(this.spliterator(), true)
for (BeanDefinition beanDefinition : componentProvider.findCandidateComponents(packageName)) { .flatMap(packageName -> componentProvider.findCandidateComponents(packageName).stream())
try { .forEach(beanDefinition -> {
componentClasses.add(ClassUtils.forName(beanDefinition.getBeanClassName(), entityClassLoader)); Optional.ofNullable(beanDefinition.getBeanClassName())
} .filter(StringUtils::hasText)
catch (ClassNotFoundException ignore) { .ifPresent(beanClassName -> {
log.warn(String.format("Class not found for component type [%s]", try {
beanDefinition.getBeanClassName())); componentClasses.add(ClassUtils.forName(beanClassName, entityClassLoader));
} }
} catch (ClassNotFoundException ignore) {
} log.warn(String.format("Class for component type [%s] not found",
beanDefinition.getBeanClassName()));
}
});
});
return componentClasses; return componentClasses;
} }
@@ -245,13 +255,8 @@ public class GemFireComponentClassTypeScanner implements Iterable<String> {
ClassPathScanningCandidateComponentProvider componentProvider = ClassPathScanningCandidateComponentProvider componentProvider =
new ClassPathScanningCandidateComponentProvider(useDefaultFilters, getEnvironment()); new ClassPathScanningCandidateComponentProvider(useDefaultFilters, getEnvironment());
for (TypeFilter exclude : excludes) { this.excludes.forEach(componentProvider::addExcludeFilter);
componentProvider.addExcludeFilter(exclude); this.includes.forEach(componentProvider::addIncludeFilter);
}
for (TypeFilter include : includes) {
componentProvider.addIncludeFilter(include);
}
return componentProvider; return componentProvider;
} }
@@ -270,29 +275,23 @@ public class GemFireComponentClassTypeScanner implements Iterable<String> {
/* (non-Javadoc) */ /* (non-Javadoc) */
public GemFireComponentClassTypeScanner withExcludes(TypeFilter... excludes) { public GemFireComponentClassTypeScanner withExcludes(TypeFilter... excludes) {
return withExcludes(CollectionUtils.asSet(ArrayUtils.nullSafeArray(excludes, TypeFilter.class))); return withExcludes(asSet(nullSafeArray(excludes, TypeFilter.class)));
} }
/* (non-Javadoc) */ /* (non-Javadoc) */
public GemFireComponentClassTypeScanner withExcludes(Iterable<TypeFilter> excludes) { public GemFireComponentClassTypeScanner withExcludes(Iterable<TypeFilter> excludes) {
for (TypeFilter exclude : CollectionUtils.nullSafeIterable(excludes)) { stream(nullSafeIterable(excludes).spliterator(), false).forEach(this.excludes::add);
this.excludes.add(exclude);
}
return this; return this;
} }
/* (non-Javadoc) */ /* (non-Javadoc) */
public GemFireComponentClassTypeScanner withIncludes(TypeFilter... includes) { public GemFireComponentClassTypeScanner withIncludes(TypeFilter... includes) {
return withIncludes(CollectionUtils.asSet(ArrayUtils.nullSafeArray(includes, TypeFilter.class))); return withIncludes(asSet(nullSafeArray(includes, TypeFilter.class)));
} }
/* (non-Javadoc) */ /* (non-Javadoc) */
public GemFireComponentClassTypeScanner withIncludes(Iterable<TypeFilter> includes) { public GemFireComponentClassTypeScanner withIncludes(Iterable<TypeFilter> includes) {
for (TypeFilter include : CollectionUtils.nullSafeIterable(includes)) { stream(nullSafeIterable(includes).spliterator(), false).forEach(this.includes::add);
this.includes.add(include);
}
return this; return this;
} }
} }

View File

@@ -28,7 +28,7 @@ import java.lang.annotation.Target;
import org.apache.geode.cache.client.ClientRegionShortcut; import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.client.Pool; import org.apache.geode.cache.client.Pool;
import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.AliasFor;
import org.springframework.data.gemfire.config.xml.GemfireConstants; import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
/** /**
* {@link Annotation} defining the Client {@link org.apache.geode.cache.Region} in which the application * {@link Annotation} defining the Client {@link org.apache.geode.cache.Region} in which the application
@@ -83,7 +83,7 @@ public @interface ClientRegion {
String diskStoreName() default ""; String diskStoreName() default "";
/** /**
* Determines whether disk-based operations (used in overflow and persistent) are synchronous or asynchronous. * Determines whether disk-based operations (used in overflow and persistence) are synchronous or asynchronous.
* *
* Defaults to {@literal synchronous}. * Defaults to {@literal synchronous}.
*/ */
@@ -102,9 +102,9 @@ public @interface ClientRegion {
* data access operations sent to the corresponding {@link org.apache.geode.cache.Region} * data access operations sent to the corresponding {@link org.apache.geode.cache.Region}
* on the GemFire/Geode Server. * on the GemFire/Geode Server.
* *
* Defaults to {@literal gemfirePool}. * Defaults to {@literal DEFAULT}.
*/ */
String poolName() default GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME; String poolName() default ClientRegionFactoryBean.DEFAULT_POOL_NAME;
/** /**
* {@link ClientRegionShortcut} used by this persistent entity's client {@link org.apache.geode.cache.Region} * {@link ClientRegionShortcut} used by this persistent entity's client {@link org.apache.geode.cache.Region}

View File

@@ -79,7 +79,7 @@ public @interface LocalRegion {
String diskStoreName() default ""; String diskStoreName() default "";
/** /**
* Determines whether disk-based operations (used in overflow and persistent) are synchronous or asynchronous. * Determines whether disk-based operations (used in overflow and persistence) are synchronous or asynchronous.
* *
* Defaults to {@literal synchronous}. * Defaults to {@literal synchronous}.
*/ */

View File

@@ -91,7 +91,7 @@ public @interface PartitionRegion {
String diskStoreName() default ""; String diskStoreName() default "";
/** /**
* Determines whether disk-based operations (used in overflow and persistent) are synchronous or asynchronous. * Determines whether disk-based operations (used in overflow and persistence) are synchronous or asynchronous.
* *
* Defaults to {@literal synchronous}. * Defaults to {@literal synchronous}.
*/ */

View File

@@ -80,7 +80,7 @@ public @interface ReplicateRegion {
String diskStoreName() default ""; String diskStoreName() default "";
/** /**
* Determines whether disk-based operations (used in overflow and persistent) are synchronous or asynchronous. * Determines whether disk-based operations (used in overflow and persistence) are synchronous or asynchronous.
* *
* Defaults to {@literal synchronous}. * Defaults to {@literal synchronous}.
*/ */

View File

@@ -24,6 +24,7 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
@@ -87,17 +88,27 @@ public abstract class SpringUtils {
} }
/* (non-Javadoc) */ /* (non-Javadoc) */
public static <T> T safeGetValue(Supplier<T> supplier) { public static <T> T safeGetValue(Supplier<T> valueSupplier) {
return safeGetValue(supplier, null); return safeGetValue(valueSupplier, (T) null);
} }
/* (non-Javadoc) */ /* (non-Javadoc) */
public static <T> T safeGetValue(Supplier<T> supplier, T defaultValue) { 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 { try {
return supplier.get(); return valueSupplier.get();
} }
catch (Throwable ignore) { catch (Throwable cause) {
return defaultValue; return exceptionHandler.apply(cause);
} }
} }
} }

View File

@@ -0,0 +1,168 @@
/*
* Copyright 2010-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.gemfire.client;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.junit.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMocking;
import org.springframework.data.gemfire.test.support.IOUtils;
/**
* Integration tests for {@link org.apache.geode.cache.client.ClientCache}.
*
* @author John Blum
* @see org.junit.Test
* @see org.apache.geode.cache.GemFireCache
* @see org.apache.geode.cache.Region
* @see org.apache.geode.cache.client.ClientCache
* @see org.apache.geode.cache.client.ClientCache
* @see org.springframework.context.ConfigurableApplicationContext
* @see org.springframework.context.annotation.Bean
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
* @see org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMocking
*/
public class ClientCacheIntegrationTests {
private ConfigurableApplicationContext newApplicationContext(Class<?>... annotatedClasses) {
return new AnnotationConfigApplicationContext(annotatedClasses);
}
private boolean testClientCacheClose(Class<?> clientCacheConfiguration) {
ConfigurableApplicationContext applicationContext = null;
try {
applicationContext = newApplicationContext(clientCacheConfiguration);
ClientCache clientCache = applicationContext.getBean(ClientCache.class);
assertThat(clientCache.isClosed()).isFalse();
applicationContext.close();
return clientCache.isClosed();
}
finally {
IOUtils.close(applicationContext);
}
}
@Test
public void clientCacheIsClosed() {
assertThat(testClientCacheClose(ClosingClientCacheConfiguration.class)).isTrue();
}
@Test
public void clientCacheIsNotClosed() {
assertThat(testClientCacheClose(CloseSuppressingClientCacheConfiguration.class)).isFalse();
}
@Test
@SuppressWarnings("unchecked")
public void multipleClientCachesAreTheSame() {
ConfigurableApplicationContext applicationContextOne = newApplicationContext(MultiClientCacheConfiguration.class);
ConfigurableApplicationContext applicationContextTwo = newApplicationContext(MultiClientCacheConfiguration.class);
ClientCache clientCacheOne = applicationContextOne.getBean(ClientCache.class);
ClientCache clientCacheTwo = applicationContextTwo.getBean(ClientCache.class);
assertThat(clientCacheOne).isNotNull();
assertThat(clientCacheTwo).isSameAs(clientCacheOne);
Region regionOne = applicationContextOne.getBean(Region.class);
Region regionTwo = applicationContextTwo.getBean(Region.class);
assertThat(regionOne).isNotNull();
assertThat(regionTwo).isSameAs(regionTwo);
assertThat(clientCacheOne.isClosed()).isFalse();
assertThat(regionOne.isDestroyed()).isFalse();
applicationContextOne.close();
assertThat(clientCacheOne.isClosed()).describedAs("ClientCache was closed").isFalse();
assertThat(regionOne.isDestroyed()).describedAs("Region was destroyed").isFalse();
}
@Configuration
@EnableGemFireMocking
static class ClosingClientCacheConfiguration {
@Bean
ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean clientCache = new ClientCacheFactoryBean();
clientCache.setClose(true);
return clientCache;
}
}
@Configuration
@EnableGemFireMocking
static class CloseSuppressingClientCacheConfiguration {
@Bean
ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean clientCache = new ClientCacheFactoryBean();
clientCache.setClose(false);
return clientCache;
}
}
@Configuration
@EnableGemFireMocking(useSingletonCache = true)
static class MultiClientCacheConfiguration {
@Bean
ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean clientCache = new ClientCacheFactoryBean();
clientCache.setClose(false);
return clientCache;
}
@Bean("Example")
ClientRegionFactoryBean<Object, Object> exampleRegion(GemFireCache gemfireCache) {
ClientRegionFactoryBean<Object, Object> exampleRegion = new ClientRegionFactoryBean<>();
exampleRegion.setCache(gemfireCache);
exampleRegion.setClose(false);
exampleRegion.setDestroy(false);
exampleRegion.setLookupEnabled(true);
exampleRegion.setShortcut(ClientRegionShortcut.LOCAL);
return exampleRegion;
}
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright 2010-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.gemfire.client;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import javax.annotation.Resource;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.Region;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author David Turanski
* @author John Blum
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "client-cache.xml", initializers = GemfireTestApplicationContextInitializer.class)
public class ClientCacheTest {
@Resource(name = "ChallengeQuestions")
@SuppressWarnings("all")
private Region<?, ?> region;
@Test
public void clientCacheIsNotClosed() {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
"/org/springframework/data/gemfire/client/client-cache-no-close.xml");
Cache cache = context.getBean(Cache.class);
context.close();
assertThat(cache.isClosed(), is(false));
}
@Test
public void poolNameEqualsDefault() {
assertThat(region.getAttributes().getPoolName(), is(nullValue()));
}
}

View File

@@ -79,10 +79,13 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
@SuppressWarnings({ "deprecation", "unchecked" }) @SuppressWarnings({ "deprecation", "unchecked" })
public void testLookupFallbackUsingDefaultShortcut() throws Exception { public void testLookupFallbackUsingDefaultShortcut() throws Exception {
String testRegionName = "TestRegion"; String testRegionName = "TestRegion";
ClientCache mockClientCache = mock(ClientCache.class); ClientCache mockClientCache = mock(ClientCache.class);
ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class); ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class);
Region mockRegion = mock(Region.class); Region mockRegion = mock(Region.class);
when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.LOCAL))).thenReturn(mockClientRegionFactory); when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.LOCAL))).thenReturn(mockClientRegionFactory);
@@ -114,6 +117,7 @@ public class ClientRegionFactoryBeanTest {
Pool mockPool = mock(Pool.class); Pool mockPool = mock(Pool.class);
Resource mockSnapshot = mock(Resource.class, "Snapshot"); Resource mockSnapshot = mock(Resource.class, "Snapshot");
when(mockBeanFactory.containsBean(eq("TestPoolTwo"))).thenReturn(true);
when(mockBeanFactory.isTypeMatch(eq("TestPoolTwo"), eq(Pool.class))).thenReturn(true); when(mockBeanFactory.isTypeMatch(eq("TestPoolTwo"), eq(Pool.class))).thenReturn(true);
when(mockBeanFactory.getBean(eq("TestPoolTwo"))).thenReturn(mockPool); when(mockBeanFactory.getBean(eq("TestPoolTwo"))).thenReturn(mockPool);
when(mockPool.getName()).thenReturn("TestPoolTwo"); when(mockPool.getName()).thenReturn("TestPoolTwo");
@@ -154,8 +158,8 @@ public class ClientRegionFactoryBeanTest {
verify(mockClientRegionFactory, times(1)).setRegionTimeToLive(any(ExpirationAttributes.class)); verify(mockClientRegionFactory, times(1)).setRegionTimeToLive(any(ExpirationAttributes.class));
verify(mockClientRegionFactory, times(1)).setStatisticsEnabled(eq(true)); verify(mockClientRegionFactory, times(1)).setStatisticsEnabled(eq(true));
verify(mockClientRegionFactory, times(1)).setValueConstraint(eq(Number.class)); verify(mockClientRegionFactory, times(1)).setValueConstraint(eq(Number.class));
verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPoolTwo"));
verify(mockClientRegionFactory, times(1)).setDiskStoreName(eq("TestDiskStoreTwo")); verify(mockClientRegionFactory, times(1)).setDiskStoreName(eq("TestDiskStoreTwo"));
verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPoolTwo"));
verify(mockClientRegionFactory, times(1)).create(eq(testRegionName)); verify(mockClientRegionFactory, times(1)).create(eq(testRegionName));
verify(mockRegion, never()).loadSnapshot(any(InputStream.class)); verify(mockRegion, never()).loadSnapshot(any(InputStream.class));
} }
@@ -163,8 +167,11 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
@SuppressWarnings({ "deprecation", "unchecked" }) @SuppressWarnings({ "deprecation", "unchecked" })
public void testLookupFallbackUsingDefaultPersistentShortcut() throws Exception { public void testLookupFallbackUsingDefaultPersistentShortcut() throws Exception {
ClientCache mockClientCache = mock(ClientCache.class); ClientCache mockClientCache = mock(ClientCache.class);
ClientRegionFactory<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class); ClientRegionFactory<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class);
Region<Object, Object> mockRegion = mock(Region.class); Region<Object, Object> mockRegion = mock(Region.class);
when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.LOCAL_PERSISTENT))).thenReturn(mockClientRegionFactory); when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.LOCAL_PERSISTENT))).thenReturn(mockClientRegionFactory);
@@ -172,6 +179,7 @@ public class ClientRegionFactoryBeanTest {
BeanFactory mockBeanFactory = mock(BeanFactory.class); BeanFactory mockBeanFactory = mock(BeanFactory.class);
when(mockBeanFactory.containsBean(eq("TestPool"))).thenReturn(true);
when(mockBeanFactory.isTypeMatch(eq("TestPool"), eq(Pool.class))).thenReturn(false); when(mockBeanFactory.isTypeMatch(eq("TestPool"), eq(Pool.class))).thenReturn(false);
factoryBean.setAttributes(null); factoryBean.setAttributes(null);
@@ -187,6 +195,7 @@ public class ClientRegionFactoryBeanTest {
verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.LOCAL_PERSISTENT)); verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.LOCAL_PERSISTENT));
verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPool")); verify(mockClientRegionFactory, times(1)).setPoolName(eq("TestPool"));
verify(mockClientRegionFactory, times(1)).create(eq("TestRegion")); verify(mockClientRegionFactory, times(1)).create(eq("TestRegion"));
verify(mockBeanFactory, times(1)).containsBean(eq("TestPool"));
verify(mockBeanFactory, never()).getBean(eq("TestPool")); verify(mockBeanFactory, never()).getBean(eq("TestPool"));
verify(mockRegion, never()).loadSnapshot(any(InputStream.class)); verify(mockRegion, never()).loadSnapshot(any(InputStream.class));
} }
@@ -194,9 +203,13 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void testLookupFallbackWithSpecifiedShortcut() throws Exception { public void testLookupFallbackWithSpecifiedShortcut() throws Exception {
BeanFactory mockBeanFactory = mock(BeanFactory.class); BeanFactory mockBeanFactory = mock(BeanFactory.class);
ClientCache mockClientCache = mock(ClientCache.class); ClientCache mockClientCache = mock(ClientCache.class);
ClientRegionFactory<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class); ClientRegionFactory<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class);
Region<Object, Object> mockRegion = mock(Region.class); Region<Object, Object> mockRegion = mock(Region.class);
when(mockBeanFactory.containsBean(anyString())).thenReturn(true); when(mockBeanFactory.containsBean(anyString())).thenReturn(true);
@@ -220,9 +233,13 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void testLookupFallbackWithSubRegionCreation() throws Exception { public void testLookupFallbackWithSubRegionCreation() throws Exception {
BeanFactory mockBeanFactory = mock(BeanFactory.class); BeanFactory mockBeanFactory = mock(BeanFactory.class);
ClientCache mockClientCache = mock(ClientCache.class); ClientCache mockClientCache = mock(ClientCache.class);
ClientRegionFactory<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class); ClientRegionFactory<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class);
Region<Object, Object> mockRegion = mock(Region.class, "RootRegion"); Region<Object, Object> mockRegion = mock(Region.class, "RootRegion");
Region<Object, Object> mockSubRegion = mock(Region.class, "SubRegion"); Region<Object, Object> mockSubRegion = mock(Region.class, "SubRegion");
@@ -247,9 +264,13 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void testLookupFallbackWithUnspecifiedPool() throws Exception { public void testLookupFallbackWithUnspecifiedPool() throws Exception {
BeanFactory mockBeanFactory = mock(BeanFactory.class); BeanFactory mockBeanFactory = mock(BeanFactory.class);
ClientCache mockClientCache = mock(ClientCache.class); ClientCache mockClientCache = mock(ClientCache.class);
ClientRegionFactory<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class); ClientRegionFactory<Object, Object> mockClientRegionFactory = mock(ClientRegionFactory.class);
Region<Object, Object> mockRegion = mock(Region.class); Region<Object, Object> mockRegion = mock(Region.class);
when(mockBeanFactory.containsBean(anyString())).thenReturn(false); when(mockBeanFactory.containsBean(anyString())).thenReturn(false);
@@ -273,6 +294,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void testSetDataPolicyName() throws Exception { public void testSetDataPolicyName() throws Exception {
factoryBean.setDataPolicyName("NORMAL"); factoryBean.setDataPolicyName("NORMAL");
assertEquals(DataPolicy.NORMAL, TestUtils.readField("dataPolicy", factoryBean)); assertEquals(DataPolicy.NORMAL, TestUtils.readField("dataPolicy", factoryBean));
} }
@@ -280,6 +302,7 @@ public class ClientRegionFactoryBeanTest {
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void testSetDataPolicyNameWithInvalidName() throws Exception { public void testSetDataPolicyNameWithInvalidName() throws Exception {
try { try {
factoryBean.setDataPolicyName("INVALID"); factoryBean.setDataPolicyName("INVALID");
} }
@@ -294,6 +317,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testIsPersistent() { public void testIsPersistent() {
assertFalse(factoryBean.isPersistent()); assertFalse(factoryBean.isPersistent());
factoryBean.setPersistent(false); factoryBean.setPersistent(false);
assertFalse(factoryBean.isPersistent()); assertFalse(factoryBean.isPersistent());
@@ -303,6 +327,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testIsPersistentUnspecified() { public void testIsPersistentUnspecified() {
assertTrue(factoryBean.isPersistentUnspecified()); assertTrue(factoryBean.isPersistentUnspecified());
factoryBean.setPersistent(true); factoryBean.setPersistent(true);
assertTrue(factoryBean.isPersistent()); assertTrue(factoryBean.isPersistent());
@@ -314,6 +339,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testIsNotPersistent() { public void testIsNotPersistent() {
assertFalse(factoryBean.isNotPersistent()); assertFalse(factoryBean.isNotPersistent());
factoryBean.setPersistent(true); factoryBean.setPersistent(true);
assertFalse(factoryBean.isNotPersistent()); assertFalse(factoryBean.isNotPersistent());
@@ -323,7 +349,8 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testCloseDestroySettings() { public void testCloseDestroySettings() {
final ClientRegionFactoryBean<Object, Object> factory = new ClientRegionFactoryBean<>();
ClientRegionFactoryBean<Object, Object> factory = new ClientRegionFactoryBean<>();
assertNotNull(factory); assertNotNull(factory);
assertFalse(factory.isClose()); assertFalse(factory.isClose());
@@ -372,6 +399,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testResolveClientRegionShortcut() throws Exception { public void testResolveClientRegionShortcut() throws Exception {
assertNull(TestUtils.readField("dataPolicy", factoryBean)); assertNull(TestUtils.readField("dataPolicy", factoryBean));
assertNull(TestUtils.readField("persistent", factoryBean)); assertNull(TestUtils.readField("persistent", factoryBean));
assertNull(TestUtils.readField("shortcut", factoryBean)); assertNull(TestUtils.readField("shortcut", factoryBean));
@@ -380,6 +408,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testResolveClientRegionShortcutWhenNotPersistent() throws Exception { public void testResolveClientRegionShortcutWhenNotPersistent() throws Exception {
factoryBean.setPersistent(false); factoryBean.setPersistent(false);
assertNull(TestUtils.readField("dataPolicy", factoryBean)); assertNull(TestUtils.readField("dataPolicy", factoryBean));
@@ -390,6 +419,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testResolveClientRegionShortcutWhenPersistent() throws Exception { public void testResolveClientRegionShortcutWhenPersistent() throws Exception {
factoryBean.setPersistent(true); factoryBean.setPersistent(true);
assertNull(TestUtils.readField("dataPolicy", factoryBean)); assertNull(TestUtils.readField("dataPolicy", factoryBean));
@@ -400,6 +430,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testResolveClientRegionShortcutUsingShortcut() throws Exception { public void testResolveClientRegionShortcutUsingShortcut() throws Exception {
factoryBean.setShortcut(ClientRegionShortcut.CACHING_PROXY_OVERFLOW); factoryBean.setShortcut(ClientRegionShortcut.CACHING_PROXY_OVERFLOW);
assertNull(TestUtils.readField("dataPolicy", factoryBean)); assertNull(TestUtils.readField("dataPolicy", factoryBean));
@@ -409,6 +440,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testResolveClientRegionShortcutUsingShortcutWhenNotPersistent() throws Exception { public void testResolveClientRegionShortcutUsingShortcutWhenNotPersistent() throws Exception {
factoryBean.setPersistent(false); factoryBean.setPersistent(false);
factoryBean.setShortcut(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU); factoryBean.setShortcut(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU);
@@ -419,6 +451,7 @@ public class ClientRegionFactoryBeanTest {
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void testResolveClientRegionShortcutUsingShortcutWhenPersistent() throws Exception { public void testResolveClientRegionShortcutUsingShortcutWhenPersistent() throws Exception {
try { try {
factoryBean.setPersistent(true); factoryBean.setPersistent(true);
factoryBean.setShortcut(ClientRegionShortcut.CACHING_PROXY); factoryBean.setShortcut(ClientRegionShortcut.CACHING_PROXY);
@@ -437,6 +470,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testResolveClientRegionShortcutUsingPersistentShortcut() throws Exception { public void testResolveClientRegionShortcutUsingPersistentShortcut() throws Exception {
factoryBean.setShortcut(ClientRegionShortcut.LOCAL_PERSISTENT); factoryBean.setShortcut(ClientRegionShortcut.LOCAL_PERSISTENT);
assertNull(TestUtils.readField("dataPolicy", factoryBean)); assertNull(TestUtils.readField("dataPolicy", factoryBean));
@@ -446,6 +480,7 @@ public class ClientRegionFactoryBeanTest {
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void testResolveClientRegionShortcutUsingPersistentShortcutWhenNotPersistent() throws Exception { public void testResolveClientRegionShortcutUsingPersistentShortcutWhenNotPersistent() throws Exception {
try { try {
factoryBean.setPersistent(false); factoryBean.setPersistent(false);
factoryBean.setShortcut(ClientRegionShortcut.LOCAL_PERSISTENT); factoryBean.setShortcut(ClientRegionShortcut.LOCAL_PERSISTENT);
@@ -464,6 +499,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testResolveClientRegionShortcutUsingPersistentShortcutWhenPersistent() throws Exception { public void testResolveClientRegionShortcutUsingPersistentShortcutWhenPersistent() throws Exception {
factoryBean.setPersistent(true); factoryBean.setPersistent(true);
factoryBean.setShortcut(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW); factoryBean.setShortcut(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW);
@@ -474,6 +510,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testResolveClientRegionShortcutUsingEmptyDataPolicy() throws Exception { public void testResolveClientRegionShortcutUsingEmptyDataPolicy() throws Exception {
factoryBean.setDataPolicy(DataPolicy.EMPTY); factoryBean.setDataPolicy(DataPolicy.EMPTY);
assertNull(TestUtils.readField("persistent", factoryBean)); assertNull(TestUtils.readField("persistent", factoryBean));
@@ -483,6 +520,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testResolveClientRegionShortcutUsingNormalDataPolicyWhenNotPersistent() throws Exception { public void testResolveClientRegionShortcutUsingNormalDataPolicyWhenNotPersistent() throws Exception {
factoryBean.setDataPolicy(DataPolicy.NORMAL); factoryBean.setDataPolicy(DataPolicy.NORMAL);
factoryBean.setPersistent(false); factoryBean.setPersistent(false);
@@ -493,6 +531,7 @@ public class ClientRegionFactoryBeanTest {
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void testResolveClientRegionShortcutUsingNormalDataPolicyWhenPersistent() throws Exception { public void testResolveClientRegionShortcutUsingNormalDataPolicyWhenPersistent() throws Exception {
try { try {
factoryBean.setDataPolicy(DataPolicy.NORMAL); factoryBean.setDataPolicy(DataPolicy.NORMAL);
factoryBean.setPersistent(true); factoryBean.setPersistent(true);
@@ -510,6 +549,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testResolveClientRegionShortcutUsingPersistentReplicateDataPolicy() throws Exception { public void testResolveClientRegionShortcutUsingPersistentReplicateDataPolicy() throws Exception {
factoryBean.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE); factoryBean.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
assertNull(TestUtils.readField("persistent", factoryBean)); assertNull(TestUtils.readField("persistent", factoryBean));
@@ -519,6 +559,7 @@ public class ClientRegionFactoryBeanTest {
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void testResolveClientRegionShortcutUsingPersistentReplicateDataPolicyWhenNotPersistent() throws Exception { public void testResolveClientRegionShortcutUsingPersistentReplicateDataPolicyWhenNotPersistent() throws Exception {
try { try {
factoryBean.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE); factoryBean.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
factoryBean.setPersistent(false); factoryBean.setPersistent(false);
@@ -536,6 +577,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void testResolveClientRegionShortcutUsingPersistentReplicateDataPolicyWhenPersistent() throws Exception { public void testResolveClientRegionShortcutUsingPersistentReplicateDataPolicyWhenPersistent() throws Exception {
factoryBean.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE); factoryBean.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
factoryBean.setPersistent(true); factoryBean.setPersistent(true);
@@ -551,7 +593,8 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void destroyCallsRegionClose() throws Exception { public void destroyCallsRegionClose() throws Exception {
final Region mockRegion = mock(Region.class, "MockRegion");
Region mockRegion = mock(Region.class, "MockRegion");
RegionService mockRegionService = mock(RegionService.class, "MockRegionService"); RegionService mockRegionService = mock(RegionService.class, "MockRegionService");
@@ -585,7 +628,8 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void destroyCallsRegionDestroy() throws Exception { public void destroyCallsRegionDestroy() throws Exception {
final Region mockRegion = mock(Region.class, "MockRegion");
Region mockRegion = mock(Region.class, "MockRegion");
RegionService mockRegionService = mock(RegionService.class, "MockRegionService"); RegionService mockRegionService = mock(RegionService.class, "MockRegionService");
@@ -620,7 +664,8 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void destroyDoesNothingWhenClientRegionFactoryBeanCloseIsTrueButRegionServiceIsClosed() throws Exception { public void destroyDoesNothingWhenClientRegionFactoryBeanCloseIsTrueButRegionServiceIsClosed() throws Exception {
final Region mockRegion = mock(Region.class, "MockRegion");
Region mockRegion = mock(Region.class, "MockRegion");
RegionService mockRegionService = mock(RegionService.class, "MockRegionService"); RegionService mockRegionService = mock(RegionService.class, "MockRegionService");
@@ -654,7 +699,8 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void destroyDoesNothingWhenClientRegionFactoryBeanCloseAndDestroyAreFalse() throws Exception { public void destroyDoesNothingWhenClientRegionFactoryBeanCloseAndDestroyAreFalse() throws Exception {
final Region mockRegion = mock(Region.class, "MockRegion");
Region mockRegion = mock(Region.class, "MockRegion");
ClientRegionFactoryBean clientRegionFactoryBean = new ClientRegionFactoryBean() { ClientRegionFactoryBean clientRegionFactoryBean = new ClientRegionFactoryBean() {
@Override public Region getObject() throws Exception { @Override public Region getObject() throws Exception {
@@ -673,6 +719,7 @@ public class ClientRegionFactoryBeanTest {
@Test @Test
public void destroyDoesNothingWhenRegionIsNull() throws Exception { public void destroyDoesNothingWhenRegionIsNull() throws Exception {
ClientRegionFactoryBean clientRegionFactoryBean = new ClientRegionFactoryBean() { ClientRegionFactoryBean clientRegionFactoryBean = new ClientRegionFactoryBean() {
@Override public Region getObject() throws Exception { @Override public Region getObject() throws Exception {
return null; return null;

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.gemfire.client;
import static org.assertj.core.api.Assertions.assertThat;
import javax.annotation.Resource;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.annotation.Bean;
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
import org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMocking;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Integration tests for client {@link Region Regions} created with SDG's {@link ClientRegionFactoryBean}.
*
* @author John Blum
* @see org.junit.Test
* @see org.apache.geode.cache.GemFireCache
* @see org.apache.geode.cache.Region
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
* @since 2.0.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
public class ClientRegionIntegrationTests {
@Resource(name = "Example")
private Region<Object, Object> example;
@Test
public void clientRegionUsesDefaultPoolWhenUnspecified() {
assertThat(this.example.getAttributes().getPoolName()).isNull();
}
@ClientCacheApplication
@EnableGemFireMocking
static class ClientRegionConfiguration {
@Bean("Example")
public ClientRegionFactoryBean<Object, Object> exampleRegion(GemFireCache gemfireCache) {
ClientRegionFactoryBean<Object, Object> exampleRegion = new ClientRegionFactoryBean<>();
exampleRegion.setCache(gemfireCache);
exampleRegion.setClose(false);
exampleRegion.setShortcut(ClientRegionShortcut.LOCAL);
return exampleRegion;
}
}
}

View File

@@ -37,7 +37,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringRunner;
/** /**
* The ClientRegionWithCacheLoaderWriterTest class is a test suite of test cases testing the addition of CacheLoaders * The ClientRegionWithCacheLoaderWriterTest class is a test suite of test cases testing the addition of CacheLoaders
@@ -54,8 +54,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @see org.apache.geode.cache.Region * @see org.apache.geode.cache.Region
* @since 1.3.3 * @since 1.3.3
*/ */
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringRunner.class)
@ContextConfiguration(locations = "clientcache-with-region-using-cache-loader-writer.xml") @ContextConfiguration
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class ClientRegionWithCacheLoaderWriterTest { public class ClientRegionWithCacheLoaderWriterTest {
@@ -69,6 +69,7 @@ public class ClientRegionWithCacheLoaderWriterTest {
@Test @Test
public void testCacheLoaderWriter() { public void testCacheLoaderWriter() {
assertNotNull(localAppData); assertNotNull(localAppData);
assertEquals(0, localAppData.size()); assertEquals(0, localAppData.size());
@@ -107,7 +108,7 @@ public class ClientRegionWithCacheLoaderWriterTest {
public static class LocalAppDataCacheWriter extends CacheWriterAdapter<Integer, Integer> { public static class LocalAppDataCacheWriter extends CacheWriterAdapter<Integer, Integer> {
private static final Map<Integer, Integer> data = new ConcurrentHashMap<Integer, Integer>(REGION_SIZE); private static final Map<Integer, Integer> data = new ConcurrentHashMap<>(REGION_SIZE);
@Override @Override
public void beforeUpdate(final EntryEvent<Integer, Integer> event) throws CacheWriterException { public void beforeUpdate(final EntryEvent<Integer, Integer> event) throws CacheWriterException {

View File

@@ -42,7 +42,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.data.gemfire.RegionAttributesFactoryBean; import org.springframework.data.gemfire.RegionAttributesFactoryBean;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringRunner;
/** /**
* The LocalOnlyClientCacheIntegrationTest class... * The LocalOnlyClientCacheIntegrationTest class...
@@ -50,7 +50,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author John Blum * @author John Blum
* @since 1.0.0 * @since 1.0.0
*/ */
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringRunner.class)
@ContextConfiguration @ContextConfiguration
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class LocalOnlyClientCacheIntegrationTest { public class LocalOnlyClientCacheIntegrationTest {
@@ -71,26 +71,27 @@ public class LocalOnlyClientCacheIntegrationTest {
@Test @Test
public void getAndPutsAreSuccessful() { public void getAndPutsAreSuccessful() {
assertThat(example.put(1l, "one"), is(nullValue())); assertThat(example.put(1L, "one"), is(nullValue()));
assertThat(example.put(2l, "two"), is(nullValue())); assertThat(example.put(2L, "two"), is(nullValue()));
assertThat(example.put(3l, "three"), is(nullValue())); assertThat(example.put(3L, "three"), is(nullValue()));
assertThat(example.get(1l), is(equalTo("one"))); assertThat(example.get(1L), is(equalTo("one")));
assertThat(example.get(2l), is(equalTo("two"))); assertThat(example.get(2L), is(equalTo("two")));
assertThat(example.get(3l), is(equalTo("three"))); assertThat(example.get(3L), is(equalTo("three")));
assertThat(example.get(0l), is(nullValue())); assertThat(example.get(0L), is(nullValue()));
assertThat(example.get(4l), is(nullValue())); assertThat(example.get(4L), is(nullValue()));
} }
@Configuration @Configuration
static class GemFireClientCacheConfiguration { static class GemFireClientCacheConfiguration {
@Bean @Bean
PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer(); return new PropertySourcesPlaceholderConfigurer();
} }
@Bean @Bean
Properties gemfireProperties(@Value("${spring.data.gemfire.log.level:warning}") String logLevel) { Properties gemfireProperties(@Value("${spring.data.gemfire.log.level:warning}") String logLevel) {
Properties gemfireProperties = new Properties(); Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", LocalOnlyClientCacheIntegrationTest.class.getSimpleName()); gemfireProperties.setProperty("name", LocalOnlyClientCacheIntegrationTest.class.getSimpleName());
@@ -101,6 +102,7 @@ public class LocalOnlyClientCacheIntegrationTest {
@Bean @Bean
ClientCacheFactoryBean gemfireCache(@Qualifier("gemfireProperties") Properties gemfireProperties) { ClientCacheFactoryBean gemfireCache(@Qualifier("gemfireProperties") Properties gemfireProperties) {
ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean(); ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean();
gemfireCache.setClose(true); gemfireCache.setClose(true);
@@ -128,6 +130,7 @@ public class LocalOnlyClientCacheIntegrationTest {
@Bean @Bean
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
RegionAttributesFactoryBean exampleRegionAttributes() { RegionAttributesFactoryBean exampleRegionAttributes() {
RegionAttributesFactoryBean exampleRegionAttributes = new RegionAttributesFactoryBean(); RegionAttributesFactoryBean exampleRegionAttributes = new RegionAttributesFactoryBean();
exampleRegionAttributes.setKeyConstraint(Long.class); exampleRegionAttributes.setKeyConstraint(Long.class);

View File

@@ -1,58 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.data.gemfire.client;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.Region;
import org.junit.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author David Turanski
* @author John Blum
*/
public class MultipleClientCacheTest {
@Test
public void testMultipleCaches() {
String configLocation = "/org/springframework/data/gemfire/client/client-cache-no-close.xml";
ConfigurableApplicationContext context1 = new ClassPathXmlApplicationContext(configLocation);
ConfigurableApplicationContext context2 = new ClassPathXmlApplicationContext(configLocation);
Cache cache1 = context1.getBean(Cache.class);
Cache cache2 = context2.getBean(Cache.class);
assertNotNull(cache1);
assertSame(cache1, cache2);
Region region1 = context1.getBean(Region.class);
Region region2 = context2.getBean(Region.class);
assertNotNull(region1);
assertSame(region1, region2);
assertFalse(cache1.isClosed());
assertFalse(region1.isDestroyed());
context1.close();
assertFalse(cache1.isClosed());
assertFalse("region was destroyed", region1.isDestroyed());
}
}

View File

@@ -71,7 +71,6 @@ import org.springframework.data.gemfire.config.annotation.test.entities.LocalReg
import org.springframework.data.gemfire.config.annotation.test.entities.NonEntity; import org.springframework.data.gemfire.config.annotation.test.entities.NonEntity;
import org.springframework.data.gemfire.config.annotation.test.entities.PartitionRegionEntity; import org.springframework.data.gemfire.config.annotation.test.entities.PartitionRegionEntity;
import org.springframework.data.gemfire.config.annotation.test.entities.ReplicateRegionEntity; import org.springframework.data.gemfire.config.annotation.test.entities.ReplicateRegionEntity;
import org.springframework.data.gemfire.config.xml.GemfireConstants;
import org.springframework.data.gemfire.mapping.annotation.ClientRegion; import org.springframework.data.gemfire.mapping.annotation.ClientRegion;
import org.springframework.data.gemfire.mapping.annotation.LocalRegion; import org.springframework.data.gemfire.mapping.annotation.LocalRegion;
import org.springframework.data.gemfire.mapping.annotation.PartitionRegion; import org.springframework.data.gemfire.mapping.annotation.PartitionRegion;
@@ -192,20 +191,21 @@ public class EnableEntityDefinedRegionsUnitTests {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void entityClientRegionsDefined() { public void entityClientRegionsDefined() {
applicationContext = newApplicationContext(ClientPersistentEntitiesConfiguration.class); applicationContext = newApplicationContext(ClientPersistentEntitiesConfiguration.class);
Region<String, ClientRegionEntity> sessions = applicationContext.getBean("Sessions", Region.class); Region<String, ClientRegionEntity> sessions = applicationContext.getBean("Sessions", Region.class);
assertRegion(sessions, "Sessions", String.class, ClientRegionEntity.class); assertRegion(sessions, "Sessions", String.class, ClientRegionEntity.class);
assertRegionAttributes(sessions.getAttributes(), DataPolicy.NORMAL, null, true, assertRegionAttributes(sessions.getAttributes(), DataPolicy.NORMAL, null, true,
false, GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, null); false, null, null);
Region<Long, GenericRegionEntity> genericRegionEntity = Region<Long, GenericRegionEntity> genericRegionEntity =
applicationContext.getBean("GenericRegionEntity", Region.class); applicationContext.getBean("GenericRegionEntity", Region.class);
assertRegion(genericRegionEntity, "GenericRegionEntity", Long.class, GenericRegionEntity.class); assertRegion(genericRegionEntity, "GenericRegionEntity", Long.class, GenericRegionEntity.class);
assertRegionAttributes(genericRegionEntity.getAttributes(), DataPolicy.EMPTY, null, assertRegionAttributes(genericRegionEntity.getAttributes(), DataPolicy.EMPTY, null,
true, false, GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, null); true, false, null, null);
assertThat(applicationContext.containsBean("CollocatedPartitionRegionEntity")).isFalse(); assertThat(applicationContext.containsBean("CollocatedPartitionRegionEntity")).isFalse();
assertThat(applicationContext.containsBean("ContactEvents")).isFalse(); assertThat(applicationContext.containsBean("ContactEvents")).isFalse();

View File

@@ -236,6 +236,7 @@ public class ClientRegionNamespaceTest {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void testClientRegionWithAttributes() { public void testClientRegionWithAttributes() {
assertTrue(applicationContext.containsBean("client-with-attributes")); assertTrue(applicationContext.containsBean("client-with-attributes"));
Region<Long, String> clientRegion = applicationContext.getBean("client-with-attributes", Region.class); Region<Long, String> clientRegion = applicationContext.getBean("client-with-attributes", Region.class);

View File

@@ -47,30 +47,40 @@ import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.apache.geode.cache.Cache; import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory; import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.CustomExpiry;
import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.DiskStore; import org.apache.geode.cache.DiskStore;
import org.apache.geode.cache.DiskStoreFactory; import org.apache.geode.cache.DiskStoreFactory;
import org.apache.geode.cache.EvictionAttributes;
import org.apache.geode.cache.ExpirationAction;
import org.apache.geode.cache.ExpirationAttributes;
import org.apache.geode.cache.GemFireCache; import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region; import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes; import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.RegionService; import org.apache.geode.cache.RegionService;
import org.apache.geode.cache.client.ClientCache; import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.ClientCacheFactory; import org.apache.geode.cache.client.ClientCacheFactory;
import org.apache.geode.cache.client.ClientRegionFactory;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.client.Pool; import org.apache.geode.cache.client.Pool;
import org.apache.geode.cache.client.PoolFactory; import org.apache.geode.cache.client.PoolFactory;
import org.apache.geode.cache.control.ResourceManager; import org.apache.geode.cache.control.ResourceManager;
import org.apache.geode.cache.server.CacheServer; import org.apache.geode.cache.server.CacheServer;
import org.apache.geode.cache.server.ClientSubscriptionConfig; import org.apache.geode.cache.server.ClientSubscriptionConfig;
import org.apache.geode.compression.Compressor;
import org.apache.geode.distributed.DistributedSystem; import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.pdx.PdxSerializer; import org.apache.geode.pdx.PdxSerializer;
import org.mockito.ArgumentMatchers;
import org.springframework.data.gemfire.server.SubscriptionEvictionPolicy; import org.springframework.data.gemfire.server.SubscriptionEvictionPolicy;
import org.springframework.data.gemfire.test.support.FileSystemUtils; import org.springframework.data.gemfire.test.support.FileSystemUtils;
@@ -97,12 +107,25 @@ import org.springframework.data.gemfire.test.support.FileSystemUtils;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
private static final boolean DEFAULT_USE_SINGLETON_CACHE = false;
private static final AtomicReference<GemFireCache> singletonCache = new AtomicReference<>(null);
private static final Map<String, DiskStore> diskStores = new ConcurrentHashMap<>(); private static final Map<String, DiskStore> diskStores = new ConcurrentHashMap<>();
private static final Map<String, Region<Object, Object>> regions = new ConcurrentHashMap<>(); private static final Map<String, Region<Object, Object>> regions = new ConcurrentHashMap<>();
private static final Map<String, RegionAttributes<Object, Object>> regionAttributes = new ConcurrentHashMap<>(); private static final Map<String, RegionAttributes<Object, Object>> regionAttributes = new ConcurrentHashMap<>();
private static final String REPEATING_REGION_SEPARATOR = Region.SEPARATOR + "{2,}";
public static void destroy() {
singletonCache.set(null);
diskStores.clear();
regions.clear();
regionAttributes.clear();
}
/* (non-Javadoc) */ /* (non-Javadoc) */
private static boolean isRootRegion(Region<?, ?> region) { private static boolean isRootRegion(Region<?, ?> region) {
return isRootRegion(region.getFullPath()); return isRootRegion(region.getFullPath());
@@ -113,9 +136,38 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
return (regionPath.lastIndexOf(Region.SEPARATOR) <= 0); return (regionPath.lastIndexOf(Region.SEPARATOR) <= 0);
} }
/* (non-Javadoc) */
private static String normalizeRegionPath(String regionPath) {
regionPath = regionPath.replaceAll(REPEATING_REGION_SEPARATOR, Region.SEPARATOR);
regionPath = regionPath.endsWith(Region.SEPARATOR)
? regionPath.substring(0, regionPath.length() - 1) : regionPath;
return regionPath;
}
/* (non-Javadoc) */
private static String toRegionName(String regionName) {
return Optional.ofNullable(regionName)
.map(String::trim)
.map(it -> {
int lastIndexOfRegionSeparator = it.lastIndexOf(Region.SEPARATOR);
return lastIndexOfRegionSeparator < 0 ? it : it.substring(lastIndexOfRegionSeparator);
})
.filter(it -> !it.isEmpty())
.orElseThrow(() -> newIllegalArgumentException("Region name [%s] is required", regionName));
}
/* (non-Javadoc) */
private static String toRegionPath(String regionPath) { private static String toRegionPath(String regionPath) {
return (StringUtils.startsWith(regionPath, Region.SEPARATOR) ? regionPath
: String.format("%1$s%2$s", Region.SEPARATOR, regionPath)); return Optional.ofNullable(regionPath)
.map(String::trim)
.map(it -> it.startsWith(Region.SEPARATOR) ? it : String.format("%1$s%2$s", Region.SEPARATOR, it))
.map(MockGemFireObjectsSupport::normalizeRegionPath)
.filter(it -> !it.isEmpty())
.orElseThrow(() -> newIllegalArgumentException("Region path [%s] is required", regionPath));
} }
/* (non-Javadoc) */ /* (non-Javadoc) */
@@ -183,18 +235,8 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
when(mockRegionService.createPdxInstanceFactory(anyString())) when(mockRegionService.createPdxInstanceFactory(anyString()))
.thenThrow(newUnsupportedOperationException(NOT_SUPPORTED)); .thenThrow(newUnsupportedOperationException(NOT_SUPPORTED));
when(mockRegionService.rootRegions()).thenAnswer(invocation -> { when(mockRegionService.rootRegions()).thenAnswer(invocation ->
regions.values().stream().filter(MockGemFireObjectsSupport::isRootRegion).collect(Collectors.toSet()));
Set<Region<Object, Object>> rootRegions = new HashSet<>();
for (Region<Object, Object> region : regions.values()) {
if (isRootRegion(region)) {
rootRegions.add(region);
}
}
return rootRegions;
});
return mockRegionService; return mockRegionService;
} }
@@ -203,7 +245,9 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
ClientCache mockClientCache = mock(ClientCache.class); ClientCache mockClientCache = mock(ClientCache.class);
return mockCacheApi(mockClientCache); doAnswer(newVoidAnswer(invocation -> mockClientCache.close())).when(mockClientCache).close(anyBoolean());
return mockClientRegionFactory(mockCacheApi(mockClientCache));
} }
public static GemFireCache mockGemFireCache() { public static GemFireCache mockGemFireCache() {
@@ -320,6 +364,131 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
return mockCacheServer; return mockCacheServer;
} }
@SuppressWarnings("unchecked")
public static <K, V> ClientCache mockClientRegionFactory(ClientCache mockClientCache) {
ClientRegionFactory<K, V> mockClientRegionFactory =
mock(ClientRegionFactory.class, mockObjectIdentifier("MockClientRegionFactory"));
when(mockClientCache.<K, V>createClientRegionFactory(any(ClientRegionShortcut.class)))
.thenReturn(mockClientRegionFactory);
ExpirationAttributes DEFAULT_EXPIRATION_ATTRIBUTES =
new ExpirationAttributes(0, ExpirationAction.INVALIDATE);
AtomicBoolean cloningEnabled = new AtomicBoolean(false);
AtomicBoolean concurrencyChecksEnabled = new AtomicBoolean(false);
AtomicBoolean diskSynchronous = new AtomicBoolean(true);
AtomicBoolean statisticsEnabled = new AtomicBoolean(false);
AtomicInteger concurrencyLevel = new AtomicInteger(16);
AtomicInteger initialCapacity = new AtomicInteger(16);
AtomicReference<Compressor> compressor = new AtomicReference<>(null);
AtomicReference<CustomExpiry<K, V>> customEntryIdleTimeout = new AtomicReference<>(null);
AtomicReference<CustomExpiry<K, V>> customEntryTimeToLive = new AtomicReference<>(null);
AtomicReference<String> diskStoreName = new AtomicReference<>(null);
AtomicReference<ExpirationAttributes> entryIdleTimeout = new AtomicReference<>(DEFAULT_EXPIRATION_ATTRIBUTES);
AtomicReference<ExpirationAttributes> entryTimeToLive = new AtomicReference<>(DEFAULT_EXPIRATION_ATTRIBUTES);
AtomicReference<EvictionAttributes> evictionAttributes =
new AtomicReference<>(EvictionAttributes.createLRUEntryAttributes());
AtomicReference<Class<K>> keyConstraint = new AtomicReference<>();
AtomicReference<Float> loadFactor = new AtomicReference<>(0.75f);
AtomicReference<String> poolName = new AtomicReference<>(null);
AtomicReference<ExpirationAttributes> regionIdleTimeout = new AtomicReference<>(DEFAULT_EXPIRATION_ATTRIBUTES);
AtomicReference<ExpirationAttributes> regionTimeToLive = new AtomicReference<>(DEFAULT_EXPIRATION_ATTRIBUTES);
AtomicReference<Class<K>> valueConstraint = new AtomicReference<>();
when(mockClientRegionFactory.setCloningEnabled(anyBoolean()))
.thenAnswer(newSetter(cloningEnabled, mockClientRegionFactory));
when(mockClientRegionFactory.setCompressor(any(Compressor.class)))
.thenAnswer(newSetter(compressor, mockClientRegionFactory));
doAnswer(newSetter(concurrencyChecksEnabled, mockClientRegionFactory))
.when(mockClientRegionFactory).setConcurrencyChecksEnabled(anyBoolean());
when(mockClientRegionFactory.setConcurrencyLevel(anyInt()))
.thenAnswer(newSetter(concurrencyLevel, mockClientRegionFactory));
when(mockClientRegionFactory.setCustomEntryIdleTimeout(any(CustomExpiry.class)))
.thenAnswer(newSetter(customEntryIdleTimeout, mockClientRegionFactory));
when(mockClientRegionFactory.setCustomEntryTimeToLive(any(CustomExpiry.class)))
.thenAnswer(newSetter(customEntryTimeToLive, mockClientRegionFactory));
when(mockClientRegionFactory.setDiskStoreName(anyString()))
.thenAnswer(newSetter(diskStoreName, mockClientRegionFactory));
when(mockClientRegionFactory.setDiskSynchronous(anyBoolean()))
.thenAnswer(newSetter(diskSynchronous, mockClientRegionFactory));
when(mockClientRegionFactory.setEntryIdleTimeout(any(ExpirationAttributes.class)))
.thenAnswer(newSetter(entryIdleTimeout, mockClientRegionFactory));
when(mockClientRegionFactory.setEntryTimeToLive(any(ExpirationAttributes.class)))
.thenAnswer(newSetter(entryTimeToLive, mockClientRegionFactory));
when(mockClientRegionFactory.setEvictionAttributes(any(EvictionAttributes.class)))
.thenAnswer(newSetter(evictionAttributes, mockClientRegionFactory));
when(mockClientRegionFactory.setInitialCapacity(anyInt()))
.thenAnswer(newSetter(initialCapacity, mockClientRegionFactory));
when(mockClientRegionFactory.setKeyConstraint(any(Class.class)))
.thenAnswer(newSetter(keyConstraint, mockClientRegionFactory));
when(mockClientRegionFactory.setLoadFactor(anyFloat()))
.thenAnswer(newSetter(loadFactor, mockClientRegionFactory));
when(mockClientRegionFactory.setPoolName(anyString()))
.thenAnswer(newSetter(poolName, mockClientRegionFactory));
when(mockClientRegionFactory.setRegionIdleTimeout(any(ExpirationAttributes.class)))
.thenAnswer(newSetter(regionIdleTimeout, mockClientRegionFactory));
when(mockClientRegionFactory.setRegionTimeToLive(any(ExpirationAttributes.class)))
.thenAnswer(newSetter(regionTimeToLive, mockClientRegionFactory));
when(mockClientRegionFactory.setStatisticsEnabled(anyBoolean()))
.thenAnswer(newSetter(statisticsEnabled, mockClientRegionFactory));
when(mockClientRegionFactory.setValueConstraint(any(Class.class)))
.thenAnswer(newSetter(valueConstraint, mockClientRegionFactory));
RegionAttributes<K, V> mockRegionAttributes =
mock(RegionAttributes.class, mockObjectIdentifier("MockRegionAttributes"));
when(mockRegionAttributes.getCloningEnabled()).thenAnswer(newGetter(cloningEnabled));
when(mockRegionAttributes.getCompressor()).thenAnswer(newGetter(compressor));
when(mockRegionAttributes.getConcurrencyChecksEnabled()).thenAnswer(newGetter(concurrencyChecksEnabled));
when(mockRegionAttributes.getConcurrencyLevel()).thenAnswer(newGetter(concurrencyLevel));
when(mockRegionAttributes.getCustomEntryIdleTimeout()).thenAnswer(newGetter(customEntryIdleTimeout));
when(mockRegionAttributes.getCustomEntryTimeToLive()).thenAnswer(newGetter(customEntryTimeToLive));
when(mockRegionAttributes.getDataPolicy()).thenReturn(DataPolicy.NORMAL);
when(mockRegionAttributes.getDiskStoreName()).thenAnswer(newGetter(diskStoreName));
when(mockRegionAttributes.isDiskSynchronous()).thenAnswer(newGetter(diskSynchronous));
when(mockRegionAttributes.getEntryIdleTimeout()).thenAnswer(newGetter(entryIdleTimeout));
when(mockRegionAttributes.getEntryTimeToLive()).thenAnswer(newGetter(entryTimeToLive));
when(mockRegionAttributes.getEvictionAttributes()).thenAnswer(newGetter(evictionAttributes));
when(mockRegionAttributes.getInitialCapacity()).thenAnswer(newGetter(initialCapacity));
when(mockRegionAttributes.getKeyConstraint()).thenAnswer(newGetter(keyConstraint));
when(mockRegionAttributes.getLoadFactor()).thenAnswer(newGetter(loadFactor));
when(mockRegionAttributes.getPoolName()).thenAnswer(newGetter(poolName));
when(mockRegionAttributes.getRegionIdleTimeout()).thenAnswer(newGetter(regionIdleTimeout));
when(mockRegionAttributes.getRegionTimeToLive()).thenAnswer(newGetter(regionTimeToLive));
when(mockRegionAttributes.getStatisticsEnabled()).thenAnswer(newGetter(statisticsEnabled));
when(mockRegionAttributes.getValueConstraint()).thenAnswer(newGetter(valueConstraint));
when(mockClientRegionFactory.create(anyString())).thenAnswer(invocation ->
mockRegion(mockClientCache, invocation.getArgument(0), mockRegionAttributes));
when(mockClientRegionFactory.createSubregion(any(Region.class), anyString())).thenAnswer(invocation ->
mockSubRegion(invocation.getArgument(0), invocation.getArgument(1), mockRegionAttributes));
return mockClientCache;
}
public static ClientSubscriptionConfig mockClientSubscriptionConfig() { public static ClientSubscriptionConfig mockClientSubscriptionConfig() {
ClientSubscriptionConfig mockClientSubscriptionConfig = mock(ClientSubscriptionConfig.class); ClientSubscriptionConfig mockClientSubscriptionConfig = mock(ClientSubscriptionConfig.class);
@@ -604,7 +773,66 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
}); });
return mockPoolFactory; return mockPoolFactory;
}
@SuppressWarnings("unchecked")
public static <K, V> Region<K, V> mockRegion(RegionService regionService, String name,
RegionAttributes<K, V> regionAttributes) {
Map<K, V> data = new ConcurrentHashMap<>();
Region<K, V> mockRegion = mock(Region.class, name);
Set<Region<?, ?>> subRegions = new CopyOnWriteArraySet<>();
when(mockRegion.getAttributes()).thenReturn(regionAttributes);
when(mockRegion.getFullPath()).thenReturn(toRegionPath(name));
when(mockRegion.getName()).thenReturn(toRegionName(name));
when(mockRegion.getRegionService()).thenReturn(regionService);
when(mockRegion.getSubregion(anyString())).thenAnswer(invocation -> {
String subRegionPath = toRegionPath(invocation.getArgument(0));
String subRegionFullPath = String.format("%1$s%2$s", mockRegion.getFullPath(), subRegionPath);
return regions.get(subRegionFullPath);
});
when(mockRegion.get(ArgumentMatchers.<K>any())).thenAnswer(invocation ->
data.get(invocation.<K>getArgument(0)));
when(mockRegion.getEntry(ArgumentMatchers.<K>any())).thenAnswer(invocation ->
data.entrySet().stream().filter(entry -> entry.getKey().equals(invocation.getArgument(0))).findFirst());
when(mockRegion.put(any(), any())).thenAnswer(invocation ->
data.put(invocation.getArgument(0), invocation.getArgument(1)));
when(mockRegion.size()).thenAnswer(invocation -> data.size());
when(mockRegion.subregions(anyBoolean())).thenAnswer(invocation -> {
boolean recursive = invocation.getArgument(0);
return recursive ? subRegions.stream()
.flatMap(subRegion -> subRegion.subregions(true).stream()).collect(Collectors.toSet())
: subRegions;
});
regions.put(mockRegion.getFullPath(), (Region) mockRegion);
return mockRegion;
}
public static <K, V> Region<K, V> mockSubRegion(Region<K, V> parent, String name,
RegionAttributes<K, V> regionAttributes) {
String subRegionName = String.format("%1$s%2$s", parent.getFullPath(), toRegionPath(name));
Region<K, V> mockSubRegion = mockRegion(parent.getRegionService(), subRegionName, regionAttributes);
parent.subregions(false).add(mockSubRegion);
return mockSubRegion;
} }
public static ResourceManager mockResourceManager() { public static ResourceManager mockResourceManager() {
@@ -644,195 +872,235 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
return mockResourceManager; return mockResourceManager;
} }
private static <T extends GemFireCache> T rememberMockedGemFireCache(T mockedGemFireCache,
boolean useSingletonCache) {
return Optional.ofNullable(mockedGemFireCache)
.map(it -> {
if (useSingletonCache) {
singletonCache.compareAndSet(null, mockedGemFireCache);
}
return mockedGemFireCache;
})
.orElseThrow(() -> newIllegalArgumentException("GemFireCache is required"));
}
@SuppressWarnings("unchecked")
private static <T extends GemFireCache> Optional<T> resolveMockedGemFireCache(boolean useSingletonCache) {
return Optional.ofNullable((T) singletonCache.get()).filter(it -> useSingletonCache);
}
public static CacheFactory spyOn(CacheFactory cacheFactory) { public static CacheFactory spyOn(CacheFactory cacheFactory) {
return spyOn(cacheFactory, DEFAULT_USE_SINGLETON_CACHE);
}
public static CacheFactory spyOn(CacheFactory cacheFactory, boolean useSingletonCache) {
CacheFactory cacheFactorySpy = spy(cacheFactory); CacheFactory cacheFactorySpy = spy(cacheFactory);
Cache mockCache = mockPeerCache(); Cache resolvedMockCache = MockGemFireObjectsSupport.<Cache>resolveMockedGemFireCache(useSingletonCache)
.orElseGet(() -> {
AtomicBoolean pdxIgnoreUnreadFields = new AtomicBoolean(false); Cache mockCache = mockPeerCache();
AtomicBoolean pdxPersistent = new AtomicBoolean(false);
AtomicBoolean pdxReadSerialized = new AtomicBoolean(false);
AtomicReference<String> pdxDiskStoreName = new AtomicReference<>(null); AtomicBoolean pdxIgnoreUnreadFields = new AtomicBoolean(false);
AtomicReference<PdxSerializer> pdxSerializer = new AtomicReference<>(null); AtomicBoolean pdxPersistent = new AtomicBoolean(false);
AtomicBoolean pdxReadSerialized = new AtomicBoolean(false);
doAnswer(newSetter(pdxDiskStoreName, cacheFactorySpy)) AtomicReference<String> pdxDiskStoreName = new AtomicReference<>(null);
.when(cacheFactorySpy).setPdxDiskStore(anyString()); AtomicReference<PdxSerializer> pdxSerializer = new AtomicReference<>(null);
doAnswer(newSetter(pdxIgnoreUnreadFields, cacheFactorySpy)) doAnswer(newSetter(pdxDiskStoreName, cacheFactorySpy))
.when(cacheFactorySpy).setPdxIgnoreUnreadFields(anyBoolean()); .when(cacheFactorySpy).setPdxDiskStore(anyString());
doAnswer(newSetter(pdxPersistent, cacheFactorySpy)) doAnswer(newSetter(pdxIgnoreUnreadFields, cacheFactorySpy))
.when(cacheFactorySpy).setPdxPersistent(anyBoolean()); .when(cacheFactorySpy).setPdxIgnoreUnreadFields(anyBoolean());
doAnswer(newSetter(pdxReadSerialized, cacheFactorySpy)) doAnswer(newSetter(pdxPersistent, cacheFactorySpy))
.when(cacheFactorySpy).setPdxReadSerialized(anyBoolean()); .when(cacheFactorySpy).setPdxPersistent(anyBoolean());
doAnswer(newSetter(pdxSerializer, cacheFactorySpy)) doAnswer(newSetter(pdxReadSerialized, cacheFactorySpy))
.when(cacheFactorySpy).setPdxSerializer(any(PdxSerializer.class)); .when(cacheFactorySpy).setPdxReadSerialized(anyBoolean());
doReturn(mockCache).when(cacheFactorySpy).create(); doAnswer(newSetter(pdxSerializer, cacheFactorySpy))
.when(cacheFactorySpy).setPdxSerializer(any(PdxSerializer.class));
when(mockCache.getPdxDiskStore()).thenAnswer(newGetter(pdxDiskStoreName)); when(mockCache.getPdxDiskStore()).thenAnswer(newGetter(pdxDiskStoreName));
when(mockCache.getPdxIgnoreUnreadFields()).thenAnswer(newGetter(pdxIgnoreUnreadFields)); when(mockCache.getPdxIgnoreUnreadFields()).thenAnswer(newGetter(pdxIgnoreUnreadFields));
when(mockCache.getPdxPersistent()).thenAnswer(newGetter(pdxPersistent)); when(mockCache.getPdxPersistent()).thenAnswer(newGetter(pdxPersistent));
when(mockCache.getPdxReadSerialized()).thenAnswer(newGetter(pdxReadSerialized)); when(mockCache.getPdxReadSerialized()).thenAnswer(newGetter(pdxReadSerialized));
when(mockCache.getPdxSerializer()).thenAnswer(newGetter(pdxSerializer)); when(mockCache.getPdxSerializer()).thenAnswer(newGetter(pdxSerializer));
return mockCache;
});
doReturn(rememberMockedGemFireCache(resolvedMockCache, useSingletonCache)).when(cacheFactorySpy).create();
return cacheFactorySpy; return cacheFactorySpy;
} }
public static ClientCacheFactory spyOn(ClientCacheFactory clientCacheFactory) { public static ClientCacheFactory spyOn(ClientCacheFactory clientCacheFactory) {
return spyOn(clientCacheFactory, DEFAULT_USE_SINGLETON_CACHE);
}
public static ClientCacheFactory spyOn(ClientCacheFactory clientCacheFactory, boolean useSingletonCache) {
ClientCacheFactory clientCacheFactorySpy = spy(clientCacheFactory); ClientCacheFactory clientCacheFactorySpy = spy(clientCacheFactory);
ClientCache mockClientCache = mockClientCache(); ClientCache resolvedMockedClientCache =
MockGemFireObjectsSupport.<ClientCache>resolveMockedGemFireCache(useSingletonCache).orElseGet(() -> {
AtomicBoolean pdxIgnoreUnreadFields = new AtomicBoolean(false); ClientCache mockClientCache = mockClientCache();
AtomicBoolean pdxPersistent = new AtomicBoolean(false);
AtomicBoolean pdxReadSerialized = new AtomicBoolean(false);
AtomicReference<String> pdxDiskStoreName = new AtomicReference<>(null); AtomicBoolean pdxIgnoreUnreadFields = new AtomicBoolean(false);
AtomicReference<PdxSerializer> pdxSerializer = new AtomicReference<>(null); AtomicBoolean pdxPersistent = new AtomicBoolean(false);
AtomicReference<Pool> defaultPool = new AtomicReference<>(null); AtomicBoolean pdxReadSerialized = new AtomicBoolean(false);
doAnswer(newSetter(pdxDiskStoreName, clientCacheFactorySpy)) AtomicReference<String> pdxDiskStoreName = new AtomicReference<>(null);
.when(clientCacheFactorySpy).setPdxDiskStore(anyString()); AtomicReference<PdxSerializer> pdxSerializer = new AtomicReference<>(null);
AtomicReference<Pool> defaultPool = new AtomicReference<>(null);
doAnswer(newSetter(pdxIgnoreUnreadFields, clientCacheFactorySpy)) doAnswer(newSetter(pdxDiskStoreName, clientCacheFactorySpy))
.when(clientCacheFactorySpy).setPdxIgnoreUnreadFields(anyBoolean()); .when(clientCacheFactorySpy).setPdxDiskStore(anyString());
doAnswer(newSetter(pdxPersistent, clientCacheFactorySpy)) doAnswer(newSetter(pdxIgnoreUnreadFields, clientCacheFactorySpy))
.when(clientCacheFactorySpy).setPdxPersistent(anyBoolean()); .when(clientCacheFactorySpy).setPdxIgnoreUnreadFields(anyBoolean());
doAnswer(newSetter(pdxReadSerialized, clientCacheFactorySpy)) doAnswer(newSetter(pdxPersistent, clientCacheFactorySpy))
.when(clientCacheFactorySpy).setPdxReadSerialized(anyBoolean()); .when(clientCacheFactorySpy).setPdxPersistent(anyBoolean());
doAnswer(newSetter(pdxSerializer, clientCacheFactorySpy)) doAnswer(newSetter(pdxReadSerialized, clientCacheFactorySpy))
.when(clientCacheFactorySpy).setPdxSerializer(any(PdxSerializer.class)); .when(clientCacheFactorySpy).setPdxReadSerialized(anyBoolean());
PoolFactory mockPoolFactory = mockPoolFactory(); doAnswer(newSetter(pdxSerializer, clientCacheFactorySpy))
.when(clientCacheFactorySpy).setPdxSerializer(any(PdxSerializer.class));
doAnswer(invocation -> { PoolFactory mockPoolFactory = mockPoolFactory();
mockPoolFactory.addLocator(invocation.getArgument(0), invocation.getArgument(1));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).addPoolLocator(anyString(), anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.addServer(invocation.getArgument(0), invocation.getArgument(1)); mockPoolFactory.addLocator(invocation.getArgument(0), invocation.getArgument(1));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).addPoolServer(anyString(), anyInt()); }).when(clientCacheFactorySpy).addPoolLocator(anyString(), anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setFreeConnectionTimeout(invocation.getArgument(0)); mockPoolFactory.addServer(invocation.getArgument(0), invocation.getArgument(1));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolFreeConnectionTimeout(anyInt()); }).when(clientCacheFactorySpy).addPoolServer(anyString(), anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setIdleTimeout(invocation.getArgument(0)); mockPoolFactory.setFreeConnectionTimeout(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolIdleTimeout(anyLong()); }).when(clientCacheFactorySpy).setPoolFreeConnectionTimeout(anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setLoadConditioningInterval(invocation.getArgument(0)); mockPoolFactory.setIdleTimeout(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolLoadConditioningInterval(anyInt()); }).when(clientCacheFactorySpy).setPoolIdleTimeout(anyLong());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setMaxConnections(invocation.getArgument(0)); mockPoolFactory.setLoadConditioningInterval(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolMaxConnections(anyInt()); }).when(clientCacheFactorySpy).setPoolLoadConditioningInterval(anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setMinConnections(invocation.getArgument(0)); mockPoolFactory.setMaxConnections(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolMinConnections(anyInt()); }).when(clientCacheFactorySpy).setPoolMaxConnections(anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setMultiuserAuthentication(invocation.getArgument(0)); mockPoolFactory.setMinConnections(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolMultiuserAuthentication(anyBoolean()); }).when(clientCacheFactorySpy).setPoolMinConnections(anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setPingInterval(invocation.getArgument(0)); mockPoolFactory.setMultiuserAuthentication(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolPingInterval(anyLong()); }).when(clientCacheFactorySpy).setPoolMultiuserAuthentication(anyBoolean());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setPRSingleHopEnabled(invocation.getArgument(0)); mockPoolFactory.setPingInterval(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolPRSingleHopEnabled(anyBoolean()); }).when(clientCacheFactorySpy).setPoolPingInterval(anyLong());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setReadTimeout(invocation.getArgument(0)); mockPoolFactory.setPRSingleHopEnabled(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolReadTimeout(anyInt()); }).when(clientCacheFactorySpy).setPoolPRSingleHopEnabled(anyBoolean());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setRetryAttempts(invocation.getArgument(0)); mockPoolFactory.setReadTimeout(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolRetryAttempts(anyInt()); }).when(clientCacheFactorySpy).setPoolReadTimeout(anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setServerGroup(invocation.getArgument(0)); mockPoolFactory.setRetryAttempts(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolServerGroup(anyString()); }).when(clientCacheFactorySpy).setPoolRetryAttempts(anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setSocketBufferSize(invocation.getArgument(0)); mockPoolFactory.setServerGroup(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolSocketBufferSize(anyInt()); }).when(clientCacheFactorySpy).setPoolServerGroup(anyString());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setStatisticInterval(invocation.getArgument(0)); mockPoolFactory.setSocketBufferSize(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolStatisticInterval(anyInt()); }).when(clientCacheFactorySpy).setPoolSocketBufferSize(anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setSubscriptionAckInterval(invocation.getArgument(0)); mockPoolFactory.setStatisticInterval(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolSubscriptionAckInterval(anyInt()); }).when(clientCacheFactorySpy).setPoolStatisticInterval(anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setSubscriptionEnabled(invocation.getArgument(0)); mockPoolFactory.setSubscriptionAckInterval(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolSubscriptionEnabled(anyBoolean()); }).when(clientCacheFactorySpy).setPoolSubscriptionAckInterval(anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setSubscriptionMessageTrackingTimeout(invocation.getArgument(0)); mockPoolFactory.setSubscriptionEnabled(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolSubscriptionMessageTrackingTimeout(anyInt()); }).when(clientCacheFactorySpy).setPoolSubscriptionEnabled(anyBoolean());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setSubscriptionRedundancy(invocation.getArgument(0)); mockPoolFactory.setSubscriptionMessageTrackingTimeout(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolSubscriptionRedundancy(anyInt()); }).when(clientCacheFactorySpy).setPoolSubscriptionMessageTrackingTimeout(anyInt());
doAnswer(invocation -> { doAnswer(invocation -> {
mockPoolFactory.setThreadLocalConnections(invocation.getArgument(0)); mockPoolFactory.setSubscriptionRedundancy(invocation.getArgument(0));
return clientCacheFactorySpy; return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolThreadLocalConnections(anyBoolean()); }).when(clientCacheFactorySpy).setPoolSubscriptionRedundancy(anyInt());
doReturn(mockClientCache).when(clientCacheFactorySpy).create(); doAnswer(invocation -> {
mockPoolFactory.setThreadLocalConnections(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy).setPoolThreadLocalConnections(anyBoolean());
when(mockClientCache.getCurrentServers()).thenAnswer(invocation -> when(mockClientCache.getCurrentServers()).thenAnswer(invocation ->
Collections.unmodifiableSet(new HashSet<>(defaultPool.get().getServers()))); Collections.unmodifiableSet(new HashSet<>(defaultPool.get().getServers())));
when(mockClientCache.getDefaultPool()).thenAnswer(invocation -> { when(mockClientCache.getDefaultPool()).thenAnswer(invocation -> {
if (defaultPool.get() == null) { if (defaultPool.get() == null) {
defaultPool.set(mockPoolFactory.create("DEFAULT")); defaultPool.set(mockPoolFactory.create("DEFAULT"));
} }
return defaultPool.get(); return defaultPool.get();
}); });
when(mockClientCache.getPdxDiskStore()).thenAnswer(newGetter(pdxDiskStoreName)); when(mockClientCache.getPdxDiskStore()).thenAnswer(newGetter(pdxDiskStoreName));
when(mockClientCache.getPdxIgnoreUnreadFields()).thenAnswer(newGetter(pdxIgnoreUnreadFields)); when(mockClientCache.getPdxIgnoreUnreadFields()).thenAnswer(newGetter(pdxIgnoreUnreadFields));
when(mockClientCache.getPdxPersistent()).thenAnswer(newGetter(pdxPersistent)); when(mockClientCache.getPdxPersistent()).thenAnswer(newGetter(pdxPersistent));
when(mockClientCache.getPdxReadSerialized()).thenAnswer(newGetter(pdxReadSerialized)); when(mockClientCache.getPdxReadSerialized()).thenAnswer(newGetter(pdxReadSerialized));
when(mockClientCache.getPdxSerializer()).thenAnswer(newGetter(pdxSerializer)); when(mockClientCache.getPdxSerializer()).thenAnswer(newGetter(pdxSerializer));
return mockClientCache;
});
doReturn(rememberMockedGemFireCache(resolvedMockedClientCache, useSingletonCache))
.when(clientCacheFactorySpy).create();
return clientCacheFactorySpy; return clientCacheFactorySpy;
} }

View File

@@ -17,13 +17,18 @@
package org.springframework.data.gemfire.test.mock; package org.springframework.data.gemfire.test.mock;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import org.springframework.util.StringUtils;
/** /**
* The {@link MockObjectsSupport} class is an abstract base class encapsulating common operations and utilities * The {@link MockObjectsSupport} class is an abstract base class encapsulating common operations and utilities
@@ -35,6 +40,19 @@ import org.mockito.stubbing.Answer;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public abstract class MockObjectsSupport { public abstract class MockObjectsSupport {
private static final AtomicLong mockObjectIdentifier = new AtomicLong(0L);
private static final String DEFAULT_MOCK_OBJECT_NAME = "MockObject";
protected static String mockObjectIdentifier() {
return mockObjectIdentifier(DEFAULT_MOCK_OBJECT_NAME);
}
protected static String mockObjectIdentifier(String mockObjectName) {
return String.format("%s%d", Optional.ofNullable(mockObjectName).filter(StringUtils::hasText)
.orElse(DEFAULT_MOCK_OBJECT_NAME), mockObjectIdentifier.incrementAndGet());
}
/* (non-Javadoc) */ /* (non-Javadoc) */
protected static Answer<Boolean> newGetter(AtomicBoolean returnValue) { protected static Answer<Boolean> newGetter(AtomicBoolean returnValue) {
return invocation -> returnValue.get(); return invocation -> returnValue.get();
@@ -60,6 +78,16 @@ public abstract class MockObjectsSupport {
return invocation -> converter.apply(returnValue.get()); return invocation -> converter.apply(returnValue.get());
} }
/* (non-Javadoc) */
protected static <R> Answer<R> newGetter(Supplier<R> returnValue) {
return invocation -> returnValue.get();
}
/* (non-Javadoc) */
protected static <R, S> Answer<S> newGetter(Supplier<R> returnValue, Function<R, S> converter) {
return invocation -> converter.apply(returnValue.get());
}
/* (non-Javadoc) */ /* (non-Javadoc) */
protected static <R> Answer<R> newSetter(AtomicBoolean argument, R returnValue) { protected static <R> Answer<R> newSetter(AtomicBoolean argument, R returnValue) {
return invocation -> { return invocation -> {
@@ -139,4 +167,12 @@ public abstract class MockObjectsSupport {
return returnValue; return returnValue;
}; };
} }
/* (non-Javadoc) */
protected static <T> Answer<Void> newVoidAnswer(Consumer<InvocationOnMock> methodInvocation) {
return invocation -> {
methodInvocation.accept(invocation);
return null;
};
}
} }

View File

@@ -23,6 +23,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import org.apache.geode.cache.GemFireCache;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
/** /**
@@ -33,6 +34,7 @@ import org.springframework.context.annotation.Import;
* @see java.lang.annotation.Inherited * @see java.lang.annotation.Inherited
* @see java.lang.annotation.Retention * @see java.lang.annotation.Retention
* @see java.lang.annotation.Target * @see java.lang.annotation.Target
* @see org.apache.geode.cache.GemFireCache
* @see org.springframework.context.annotation.Import * @see org.springframework.context.annotation.Import
* @since 2.0.0 * @since 2.0.0
*/ */
@@ -44,4 +46,13 @@ import org.springframework.context.annotation.Import;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public @interface EnableGemFireMocking { public @interface EnableGemFireMocking {
/**
* Determines whether the mock {@link GemFireCache} created for Unit Tests is a Singleton.
*
* Defaults to {@literal false}.
*
* @return a boolean value indicating whether the mock {@link GemFireCache} created for Unit Tests is a Singleton.
*/
boolean useSingletonCache() default false;
} }

View File

@@ -16,9 +16,17 @@
package org.springframework.data.gemfire.test.mock.annotation; package org.springframework.data.gemfire.test.mock.annotation;
import java.lang.annotation.Annotation;
import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport;
import org.springframework.data.gemfire.test.mock.config.MockGemFireObjectsBeanPostProcessor; import org.springframework.data.gemfire.test.mock.config.MockGemFireObjectsBeanPostProcessor;
/** /**
@@ -26,16 +34,64 @@ import org.springframework.data.gemfire.test.mock.config.MockGemFireObjectsBeanP
* containing bean definitions to configure GemFire Object mocking. * containing bean definitions to configure GemFire Object mocking.
* *
* @author John Blum * @author John Blum
* @see java.lang.annotation.Annotation
* @see org.springframework.beans.factory.config.BeanPostProcessor
* @see org.springframework.context.annotation.Bean * @see org.springframework.context.annotation.Bean
* @see org.springframework.context.annotation.Configuration * @see org.springframework.context.annotation.Configuration
* @see org.springframework.context.annotation.ImportAware
* @see org.springframework.core.annotation.AnnotationAttributes
* @see org.springframework.core.type.AnnotationMetadata
* @see org.springframework.data.gemfire.test.mock.config.MockGemFireObjectsBeanPostProcessor
* @since 2.0.0 * @since 2.0.0
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Configuration @Configuration
public class GemFireMockingConfiguration { public class GemFireMockingConfiguration implements ImportAware {
private boolean useSingletonCache = false;
@Override
public void setImportMetadata(AnnotationMetadata importingClassMetadata) {
if (isAnnotationPresent(importingClassMetadata)) {
AnnotationAttributes enableGemFireMockingAttributes = getAnnotationAttributes(importingClassMetadata);
this.useSingletonCache = enableGemFireMockingAttributes.getBoolean("useSingletonCache");
}
}
private Class<? extends Annotation> getAnnotationType() {
return EnableGemFireMocking.class;
}
private boolean isAnnotationPresent(AnnotationMetadata importingClassMetadata) {
return isAnnotationPresent(importingClassMetadata, getAnnotationType());
}
private boolean isAnnotationPresent(AnnotationMetadata importingClassMetadata,
Class<? extends Annotation> annotationType) {
return importingClassMetadata.hasAnnotation(annotationType.getName());
}
private AnnotationAttributes getAnnotationAttributes(AnnotationMetadata importingClassMetadata) {
return getAnnotationAttributes(importingClassMetadata, getAnnotationType());
}
private AnnotationAttributes getAnnotationAttributes(AnnotationMetadata importingClassMetadata,
Class<? extends Annotation> annotationType) {
return AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(annotationType.getName()));
}
@Bean @Bean
public BeanPostProcessor mockGemFireObjectsBeanPostProcessor() { public BeanPostProcessor mockGemFireObjectsBeanPostProcessor() {
return MockGemFireObjectsBeanPostProcessor.INSTANCE; return MockGemFireObjectsBeanPostProcessor.newInstance(this.useSingletonCache);
}
@EventListener
public void releaseMockResources(ContextClosedEvent event) {
MockGemFireObjectsSupport.destroy();
} }
} }

View File

@@ -51,17 +51,32 @@ import org.springframework.lang.Nullable;
*/ */
public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor { public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor {
public static final MockGemFireObjectsBeanPostProcessor INSTANCE = new MockGemFireObjectsBeanPostProcessor(); private static final boolean DEFAULT_USE_SINGLETON_CACHE = false;
private static final String GEMFIRE_PROPERTIES_BEAN_NAME = "gemfireProperties"; private static final String GEMFIRE_PROPERTIES_BEAN_NAME = "gemfireProperties";
private volatile boolean useSingletonCache;
private final AtomicReference<Properties> gemfireProperties = new AtomicReference<>(new Properties()); private final AtomicReference<Properties> gemfireProperties = new AtomicReference<>(new Properties());
public static MockGemFireObjectsBeanPostProcessor newInstance() {
return newInstance(DEFAULT_USE_SINGLETON_CACHE);
}
public static MockGemFireObjectsBeanPostProcessor newInstance(boolean useSingletonCache) {
MockGemFireObjectsBeanPostProcessor beanPostProcessor = new MockGemFireObjectsBeanPostProcessor();
beanPostProcessor.useSingletonCache = useSingletonCache;
return beanPostProcessor;
}
@Nullable @Override @Nullable @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return (isGemFireProperties(bean, beanName) ? set((Properties) bean) return (isGemFireProperties(bean, beanName) ? set((Properties) bean)
: (bean instanceof CacheFactoryBean ? spyOnCacheFactoryBean((CacheFactoryBean) bean) : (bean instanceof CacheFactoryBean ? spyOnCacheFactoryBean((CacheFactoryBean) bean, this.useSingletonCache)
: (bean instanceof PoolFactoryBean ? mockThePoolFactoryBean((PoolFactoryBean) bean) : (bean instanceof PoolFactoryBean ? mockThePoolFactoryBean((PoolFactoryBean) bean)
: bean))); : bean)));
} }
@@ -88,11 +103,11 @@ public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor {
return gemfireProperties; return gemfireProperties;
} }
private Object spyOnCacheFactoryBean(CacheFactoryBean bean) { private Object spyOnCacheFactoryBean(CacheFactoryBean bean, boolean useSingletonCache) {
return (bean instanceof ClientCacheFactoryBean return (bean instanceof ClientCacheFactoryBean
? SpyingClientCacheFactoryInitializer.spyOn((ClientCacheFactoryBean) bean) ? SpyingClientCacheFactoryInitializer.spyOn((ClientCacheFactoryBean) bean, useSingletonCache)
: SpyingCacheFactoryInitializer.spyOn(bean)); : SpyingCacheFactoryInitializer.spyOn(bean, useSingletonCache));
} }
private Object mockThePoolFactoryBean(PoolFactoryBean bean) { private Object mockThePoolFactoryBean(PoolFactoryBean bean) {
@@ -102,28 +117,44 @@ public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor {
protected static class SpyingCacheFactoryInitializer protected static class SpyingCacheFactoryInitializer
implements CacheFactoryBean.CacheFactoryInitializer<CacheFactory> { implements CacheFactoryBean.CacheFactoryInitializer<CacheFactory> {
public static CacheFactoryBean spyOn(CacheFactoryBean cacheFactoryBean) { public static CacheFactoryBean spyOn(CacheFactoryBean cacheFactoryBean, boolean useSingletonCache) {
cacheFactoryBean.setCacheFactoryInitializer(new SpyingCacheFactoryInitializer()); cacheFactoryBean.setCacheFactoryInitializer(new SpyingCacheFactoryInitializer(useSingletonCache));
return cacheFactoryBean; return cacheFactoryBean;
} }
private final boolean useSingletonCache;
protected SpyingCacheFactoryInitializer(boolean useSingletonCache) {
this.useSingletonCache = useSingletonCache;
}
@Override @Override
public CacheFactory initialize(CacheFactory cacheFactory) { public CacheFactory initialize(CacheFactory cacheFactory) {
return MockGemFireObjectsSupport.spyOn(cacheFactory); return MockGemFireObjectsSupport.spyOn(cacheFactory, useSingletonCache);
} }
} }
protected static class SpyingClientCacheFactoryInitializer protected static class SpyingClientCacheFactoryInitializer
implements CacheFactoryBean.CacheFactoryInitializer<ClientCacheFactory> { implements CacheFactoryBean.CacheFactoryInitializer<ClientCacheFactory> {
public static ClientCacheFactoryBean spyOn(ClientCacheFactoryBean clientCacheFactoryBean) { public static ClientCacheFactoryBean spyOn(ClientCacheFactoryBean clientCacheFactoryBean,
clientCacheFactoryBean.setCacheFactoryInitializer(new SpyingClientCacheFactoryInitializer()); boolean useSingletonCache) {
clientCacheFactoryBean.setCacheFactoryInitializer(
new SpyingClientCacheFactoryInitializer(useSingletonCache));
return clientCacheFactoryBean; return clientCacheFactoryBean;
} }
private final boolean useSingletonCache;
protected SpyingClientCacheFactoryInitializer(boolean useSingletonCache) {
this.useSingletonCache = useSingletonCache;
}
@Override @Override
public ClientCacheFactory initialize(ClientCacheFactory clientCacheFactory) { public ClientCacheFactory initialize(ClientCacheFactory clientCacheFactory) {
return MockGemFireObjectsSupport.spyOn(clientCacheFactory); return MockGemFireObjectsSupport.spyOn(clientCacheFactory, this.useSingletonCache);
} }
} }

View File

@@ -36,6 +36,6 @@ public class MockGemFireObjectsApplicationContextInitializer
@Override @Override
@SuppressWarnings("all") @SuppressWarnings("all")
public void initialize(ConfigurableApplicationContext applicationContext) { public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.getBeanFactory().addBeanPostProcessor(MockGemFireObjectsBeanPostProcessor.INSTANCE); applicationContext.getBeanFactory().addBeanPostProcessor(MockGemFireObjectsBeanPostProcessor.newInstance());
} }
} }

View File

@@ -24,7 +24,10 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.springframework.data.gemfire.util.ArrayUtils.asArray; import static org.springframework.data.gemfire.util.ArrayUtils.asArray;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newRuntimeException;
import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.junit.Test; import org.junit.Test;
@@ -206,18 +209,72 @@ public class SpringUtilsUnitTests {
} }
@Test @Test
public void safeGetValueReturnsSupplierValue() { public void safeGetValueReturnsSuppliedValue() {
assertThat(SpringUtils.safeGetValue(() -> "test", null)).isEqualTo("test"); assertThat(SpringUtils.safeGetValue(() -> "test")).isEqualTo("test");
}
@Test
public void safeGetValueReturnsDefaultValue() {
assertThat(SpringUtils.safeGetValue(() -> { throw new RuntimeException("error"); }, "test"))
.isEqualTo("test");
} }
@Test @Test
public void safeGetValueReturnsNull() { public void safeGetValueReturnsNull() {
assertThat(SpringUtils.<Object>safeGetValue(() -> { throw new RuntimeException("error"); })).isNull(); assertThat(SpringUtils.<Object>safeGetValue(() -> { throw newRuntimeException("error"); })).isNull();
}
@Test
public void safeGetValueReturnsDefaultValue() {
assertThat(SpringUtils.safeGetValue(() -> { throw newRuntimeException("error"); }, "test"))
.isEqualTo("test");
}
@Test
public void safeGetValueReturnsSuppliedDefaultValue() {
Supplier<String> exceptionThrowingSupplier = () -> { throw newRuntimeException("error"); };
Supplier<String> defaultValueSupplier = () -> "test";
assertThat(SpringUtils.safeGetValue(exceptionThrowingSupplier, defaultValueSupplier)).isEqualTo("test");
}
@Test
public void safeGetValueHandlesExceptionReturnsValue() {
Supplier<String> exceptionThrowingSupplier = () -> { throw newRuntimeException("error"); };
Function<Throwable, String> exceptionHandler = exception -> {
assertThat(exception).isInstanceOf(RuntimeException.class);
assertThat(exception).hasMessage("error");
assertThat(exception).hasNoCause();
return "test";
};
assertThat(SpringUtils.safeGetValue(exceptionThrowingSupplier, exceptionHandler)).isEqualTo("test");
}
@Test(expected = IllegalStateException.class)
public void safeGetValueHandlesExceptionAndCanThrowException() {
Supplier<String> exceptionThrowingSupplier = () -> { throw newRuntimeException("error"); };
Function<Throwable, String> exceptionHandler = exception -> {
assertThat(exception).isInstanceOf(RuntimeException.class);
assertThat(exception).hasMessage("error");
assertThat(exception).hasNoCause();
throw newIllegalStateException(exception, "test");
};
try {
SpringUtils.safeGetValue(exceptionThrowingSupplier, exceptionHandler);
}
catch (IllegalStateException expected) {
assertThat(expected).hasMessage("test");
assertThat(expected).hasCauseInstanceOf(RuntimeException.class);
assertThat(expected.getCause()).hasMessage("error");
assertThat(expected.getCause()).hasNoCause();
throw expected;
}
} }
} }

View File

@@ -11,7 +11,6 @@
<util:properties id="gemfireProperties"> <util:properties id="gemfireProperties">
<prop key="name">ClientCacheWithRegionUsingCacheLoaderWriterTest</prop> <prop key="name">ClientCacheWithRegionUsingCacheLoaderWriterTest</prop>
<prop key="mcast-port">0</prop>
<prop key="log-level">warning</prop> <prop key="log-level">warning</prop>
</util:properties> </util:properties>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
">
<util:properties id="gemfireProperties">
<prop key="log-level">warning</prop>
</util:properties>
<gfe:client-cache properties-ref="gemfireProperties" close="false"/>
<gfe:client-region id="Example" shortcut="LOCAL" ignore-if-exists="true"/>
</beans>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
">
<util:properties id="gemfireProperties">
<prop key="log-level">warning</prop>
</util:properties>
<gfe:client-cache properties-ref="gemfireProperties"/>
<gfe:client-region id="challengeQuestionsRegion" name="ChallengeQuestions" shortcut="LOCAL"/>
</beans>

View File

@@ -95,6 +95,7 @@
result-policy="${client.regex.interests.result-policy}"/> result-policy="${client.regex.interests.result-policy}"/>
</gfe:client-region> </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="c-listener" class="org.springframework.data.gemfire.SimpleCacheListener"/>
<bean id="testCompressor" class="org.springframework.data.gemfire.config.xml.ClientRegionNamespaceTest$TestCompressor" p:name="STD"/> <bean id="testCompressor" class="org.springframework.data.gemfire.config.xml.ClientRegionNamespaceTest$TestCompressor" p:name="STD"/>