DATAGEODE-13 - Introduce well-known, documented properties for Annotation config attributes.

This commit is contained in:
John Blum
2017-06-02 15:23:00 -07:00
parent 5ce738c2b0
commit 0ee6c6ed49
61 changed files with 3796 additions and 1204 deletions

View File

@@ -104,7 +104,7 @@ import org.springframework.util.StringUtils;
* @see org.springframework.data.gemfire.support.GemfireBeanFactoryLocator
*/
@SuppressWarnings("unused")
public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
public class CacheFactoryBean extends AbstractFactoryBeanSupport<GemFireCache>
implements DisposableBean, InitializingBean, PersistenceExceptionTranslator, Phased {
private boolean close = true;
@@ -119,7 +119,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
private Boolean pdxReadSerialized;
private Boolean useClusterConfiguration;
private Cache cache;
private GemFireCache cache;
private CacheFactoryInitializer<?> cacheFactoryInitializer;
@@ -247,10 +247,10 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
* @see org.apache.geode.cache.Cache
* @see #resolveCache()
* @see #postProcess(GemFireCache)
* @see #setCache(Cache)
* @see #setCache(GemFireCache)
*/
@SuppressWarnings("deprecation")
Cache init() {
GemFireCache init() {
ClassLoader currentThreadContextClassLoader = Thread.currentThread().getContextClassLoader();
@@ -260,7 +260,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
setCache(postProcess(resolveCache()));
Optional.ofNullable(this.<Cache>getCache()).ifPresent(cache -> {
Optional.ofNullable(this.<GemFireCache>getCache()).ifPresent(cache -> {
Optional.ofNullable(cache.getDistributedSystem()).map(DistributedSystem::getDistributedMember)
.ifPresent(member ->
@@ -290,6 +290,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
* If an existing {@link Cache} could not be found, then this method proceeds in attempting to create
* a new {@link Cache} instance.
*
* @param <T> parameterized {@link Class} type extension of {@link GemFireCache}.
* @return the resolved {@link Cache} instance.
* @see org.apache.geode.cache.Cache
* @see #fetchCache()
@@ -298,15 +299,16 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
* @see #prepareFactory(Object)
* @see #createCache(Object)
*/
protected Cache resolveCache() {
@SuppressWarnings("unchecked")
protected <T extends GemFireCache> T resolveCache() {
try {
this.cacheResolutionMessagePrefix = "Found existing";
return (Cache) fetchCache();
return (T) fetchCache();
}
catch (CacheClosedException ex) {
this.cacheResolutionMessagePrefix = "Created new";
initDynamicRegionFactory();
return (Cache) createCache(prepareFactory(initializeFactory(createFactory(resolveProperties()))));
return (T) createCache(prepareFactory(initializeFactory(createFactory(resolveProperties()))));
}
}
@@ -443,6 +445,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
* @see #registerTransactionListeners(org.apache.geode.cache.GemFireCache)
* @see #registerTransactionWriter(org.apache.geode.cache.GemFireCache)
*/
@SuppressWarnings("all")
protected <T extends GemFireCache> T postProcess(T cache) {
// load cache.xml Resource and initialize the cache
@@ -457,11 +460,14 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
});
Optional.ofNullable(getCopyOnRead()).ifPresent(cache::setCopyOnRead);
Optional.ofNullable(getGatewayConflictResolver()).ifPresent(((Cache) cache)::setGatewayConflictResolver);
Optional.ofNullable(getLockLease()).ifPresent(((Cache) cache)::setLockLease);
Optional.ofNullable(getLockTimeout()).ifPresent(((Cache) cache)::setLockTimeout);
Optional.ofNullable(getMessageSyncInterval()).ifPresent(((Cache) cache)::setMessageSyncInterval);
Optional.ofNullable(getSearchTimeout()).ifPresent(((Cache) cache)::setSearchTimeout);
if (cache instanceof Cache) {
Optional.ofNullable(getGatewayConflictResolver()).ifPresent(((Cache) cache)::setGatewayConflictResolver);
Optional.ofNullable(getLockLease()).ifPresent(((Cache) cache)::setLockLease);
Optional.ofNullable(getLockTimeout()).ifPresent(((Cache) cache)::setLockTimeout);
Optional.ofNullable(getMessageSyncInterval()).ifPresent(((Cache) cache)::setMessageSyncInterval);
Optional.ofNullable(getSearchTimeout()).ifPresent(((Cache) cache)::setSearchTimeout);
}
configureHeapPercentages(cache);
registerTransactionListeners(cache);
@@ -577,6 +583,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
* @see org.springframework.dao.DataAccessException
*/
@Override
@SuppressWarnings("all")
public DataAccessException translateExceptionIfPossible(RuntimeException exception) {
if (exception instanceof IllegalArgumentException) {
@@ -620,7 +627,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
* @param cache {@link Cache} created by this {@link CacheFactoryBean}.
* @see org.apache.geode.cache.Cache
*/
protected void setCache(Cache cache) {
protected void setCache(GemFireCache cache) {
this.cache = cache;
}
@@ -701,8 +708,9 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
* @see #getCache()
*/
@Override
public Cache getObject() throws Exception {
return Optional.ofNullable(this.<Cache>getCache()).orElseGet(this::init);
@SuppressWarnings("all")
public GemFireCache getObject() throws Exception {
return Optional.ofNullable(this.<GemFireCache>getCache()).orElseGet(this::init);
}
/**
@@ -714,7 +722,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
@Override
@SuppressWarnings("unchecked")
public Class<? extends GemFireCache> getObjectType() {
return Optional.ofNullable(getCache()).<Class>map(Object::getClass).orElse(Cache.class);
return Optional.ofNullable(this.<Cache>getCache()).<Class>map(Object::getClass).orElse(Cache.class);
}
/**

View File

@@ -63,14 +63,15 @@ public class DiskStoreFactoryBean extends AbstractFactoryBeanSupport<DiskStore>
private GemFireCache cache;
private Integer compactionThreshold;
private Integer maxOplogSize;
private Integer queueSize;
private Integer timeInterval;
private Integer writeBufferSize;
private Float diskUsageCriticalPercentage;
private Float diskUsageWarningPercentage;
private Long maxOplogSize;
private Long timeInterval;
private List<DiskStoreConfigurer> diskStoreConfigurers = Collections.emptyList();
private DiskStoreConfigurer compositeDiskStoreConfigurer = (beanName, bean) ->
@@ -312,7 +313,7 @@ public class DiskStoreFactoryBean extends AbstractFactoryBeanSupport<DiskStore>
this.diskUsageWarningPercentage = diskUsageWarningPercentage;
}
public void setMaxOplogSize(Integer maxOplogSize) {
public void setMaxOplogSize(Long maxOplogSize) {
this.maxOplogSize = maxOplogSize;
}
@@ -320,7 +321,7 @@ public class DiskStoreFactoryBean extends AbstractFactoryBeanSupport<DiskStore>
this.queueSize = queueSize;
}
public void setTimeInterval(Integer timeInterval) {
public void setTimeInterval(Long timeInterval) {
this.timeInterval = timeInterval;
}

View File

@@ -130,7 +130,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
ClientCache cache = resolveCache(gemfireCache);
ClientRegionFactory<K, V> clientRegionFactory =
configure(createClientRegionFactory(cache, resolveClientRegionShortcut()));
postProcess(configure(createClientRegionFactory(cache, resolveClientRegionShortcut())));
@SuppressWarnings("all")
Region<K, V> region = newRegion(clientRegionFactory, getParent(), regionName);
@@ -251,6 +251,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
* @see org.apache.geode.cache.DataPolicy
*/
ClientRegionShortcut resolveClientRegionShortcut() {
ClientRegionShortcut resolvedShortcut = this.shortcut;
if (resolvedShortcut == null) {

View File

@@ -192,7 +192,6 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
*/
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
configureInfrastructure(importMetadata);
configureCache(importMetadata);
configurePdx(importMetadata);
@@ -208,7 +207,6 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
* @see org.springframework.core.type.AnnotationMetadata
*/
protected void configureInfrastructure(AnnotationMetadata importMetadata) {
registerCustomEditorBeanFactoryPostProcessor(importMetadata);
registerDefinedIndexesApplicationListener(importMetadata);
registerDiskStoreDirectoryBeanPostProcessor(importMetadata);
@@ -254,19 +252,33 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
Map<String, Object> cacheMetadataAttributes =
importMetadata.getAnnotationAttributes(getAnnotationTypeName());
setCopyOnRead(Boolean.TRUE.equals(cacheMetadataAttributes.get("copyOnRead")));
setCopyOnRead(resolveProperty(cacheProperty("copy-on-read"),
Boolean.TRUE.equals(cacheMetadataAttributes.get("copyOnRead"))));
Optional.ofNullable(resolveProperty(cacheProperty("critical-heap-percentage"), (Float) null))
.ifPresent(this::setCriticalHeapPercentage);
Optional.ofNullable((Float) cacheMetadataAttributes.get("criticalHeapPercentage"))
.filter(it -> getCriticalHeapPercentage() == null)
.filter(AbstractAnnotationConfigSupport::hasValue)
.ifPresent(this::setCriticalHeapPercentage);
Optional.ofNullable(resolveProperty(cacheProperty("eviction-heap-percentage"), (Float) null))
.ifPresent(this::setEvictionHeapPercentage);
Optional.ofNullable((Float) cacheMetadataAttributes.get("evictionHeapPercentage"))
.filter(it -> getEvictionHeapPercentage() == null)
.filter(AbstractAnnotationConfigSupport::hasValue)
.ifPresent(this::setEvictionHeapPercentage);
setLogLevel((String) cacheMetadataAttributes.get("logLevel"));
setName((String) cacheMetadataAttributes.get("name"));
setUseBeanFactoryLocator(Boolean.TRUE.equals(cacheMetadataAttributes.get("useBeanFactoryLocator")));
setLogLevel(resolveProperty(cacheProperty("log-level"),
(String) cacheMetadataAttributes.get("logLevel")));
setName(resolveProperty(cacheProperty("name"),
(String) cacheMetadataAttributes.get("name")));
setUseBeanFactoryLocator(resolveProperty(propertyName("use-bean-factory-locator"),
Boolean.TRUE.equals(cacheMetadataAttributes.get("useBeanFactoryLocator"))));
}
}
@@ -286,10 +298,18 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
Map<String, Object> enablePdxAttributes = importMetadata.getAnnotationAttributes(enablePdxTypeName);
setPdxDiskStoreName((String) enablePdxAttributes.get("diskStoreName"));
setPdxIgnoreUnreadFields(Boolean.TRUE.equals(enablePdxAttributes.get("ignoreUnreadFields")));
setPdxPersistent(Boolean.TRUE.equals(enablePdxAttributes.get("persistent")));
setPdxReadSerialized(Boolean.TRUE.equals(enablePdxAttributes.get("readSerialized")));
setPdxDiskStoreName(resolveProperty(pdxProperty("disk-store-name"),
(String) enablePdxAttributes.get("diskStoreName")));
setPdxIgnoreUnreadFields(resolveProperty(pdxProperty("ignore-unread-fields"),
Boolean.TRUE.equals(enablePdxAttributes.get("ignoreUnreadFields"))));
setPdxPersistent(resolveProperty(pdxProperty("persistent"),
Boolean.TRUE.equals(enablePdxAttributes.get("persistent"))));
setPdxReadSerialized(resolveProperty(pdxProperty("read-serialized"),
Boolean.TRUE.equals(enablePdxAttributes.get("readSerialized"))));
setPdxSerializer(resolvePdxSerializer((String) enablePdxAttributes.get("serializerBeanName")));
registerPdxDiskStoreAwareBeanFactoryPostProcessor(importMetadata);
@@ -313,7 +333,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
return Optional.ofNullable(pdxSerializerBeanName)
.filter(beanFactory::containsBean)
.map(beanName -> beanFactory.getBean(beanName, PdxSerializer.class))
.orElseGet(() -> Optional.ofNullable(pdxSerializer()).orElseGet(() -> newPdxSerializer(beanFactory)));
.orElseGet(() -> Optional.ofNullable(getPdxSerializer()).orElseGet(() -> newPdxSerializer(beanFactory)));
}
/**
@@ -353,7 +373,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
/* (non-Javadoc) */
private void registerPdxDiskStoreAwareBeanFactoryPostProcessor(AnnotationMetadata importMetadata) {
Optional.ofNullable(pdxDiskStoreName())
Optional.ofNullable(getPdxDiskStoreName())
.filter(StringUtils::hasText)
.ifPresent(pdxDiskStoreName -> {
if (PDX_DISK_STORE_AWARE_BEAN_FACTORY_POST_PROCESSOR_REGISTERED.compareAndSet(false, true)) {
@@ -425,22 +445,22 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
gemfireCache.setBeanClassLoader(beanClassLoader());
gemfireCache.setBeanFactory(beanFactory());
gemfireCache.setCacheXml(cacheXml());
gemfireCache.setClose(close());
gemfireCache.setCopyOnRead(copyOnRead());
gemfireCache.setCriticalHeapPercentage(criticalHeapPercentage());
gemfireCache.setDynamicRegionSupport(dynamicRegionSupport());
gemfireCache.setEvictionHeapPercentage(evictionHeapPercentage());
gemfireCache.setGatewayConflictResolver(gatewayConflictResolver());
gemfireCache.setJndiDataSources(jndiDataSources());
gemfireCache.setCacheXml(getCacheXml());
gemfireCache.setClose(isClose());
gemfireCache.setCopyOnRead(getCopyOnRead());
gemfireCache.setCriticalHeapPercentage(getCriticalHeapPercentage());
gemfireCache.setDynamicRegionSupport(getDynamicRegionSupport());
gemfireCache.setEvictionHeapPercentage(getEvictionHeapPercentage());
gemfireCache.setGatewayConflictResolver(getGatewayConflictResolver());
gemfireCache.setJndiDataSources(getJndiDataSources());
gemfireCache.setProperties(gemfireProperties());
gemfireCache.setPdxDiskStoreName(pdxDiskStoreName());
gemfireCache.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields());
gemfireCache.setPdxPersistent(pdxPersistent());
gemfireCache.setPdxReadSerialized(pdxReadSerialized());
gemfireCache.setPdxSerializer(pdxSerializer());
gemfireCache.setTransactionListeners(transactionListeners());
gemfireCache.setTransactionWriter(transactionWriter());
gemfireCache.setPdxDiskStoreName(getPdxDiskStoreName());
gemfireCache.setPdxIgnoreUnreadFields(getPdxIgnoreUnreadFields());
gemfireCache.setPdxPersistent(getPdxPersistent());
gemfireCache.setPdxReadSerialized(getPdxReadSerialized());
gemfireCache.setPdxSerializer(getPdxSerializer());
gemfireCache.setTransactionListeners(getTransactionListeners());
gemfireCache.setTransactionWriter(getTransactionWriter());
return gemfireCache;
}
@@ -588,7 +608,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.cacheXml = cacheXml;
}
protected Resource cacheXml() {
protected Resource getCacheXml() {
return this.cacheXml;
}
@@ -597,7 +617,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.close = close;
}
protected boolean close() {
protected boolean isClose() {
return this.close;
}
@@ -606,7 +626,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.copyOnRead = copyOnRead;
}
protected boolean copyOnRead() {
protected boolean getCopyOnRead() {
return this.copyOnRead;
}
@@ -615,7 +635,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.criticalHeapPercentage = criticalHeapPercentage;
}
protected Float criticalHeapPercentage() {
protected Float getCriticalHeapPercentage() {
return this.criticalHeapPercentage;
}
@@ -624,7 +644,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.dynamicRegionSupport = dynamicRegionSupport;
}
protected DynamicRegionSupport dynamicRegionSupport() {
protected DynamicRegionSupport getDynamicRegionSupport() {
return this.dynamicRegionSupport;
}
@@ -633,7 +653,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.evictionHeapPercentage = evictionHeapPercentage;
}
protected Float evictionHeapPercentage() {
protected Float getEvictionHeapPercentage() {
return this.evictionHeapPercentage;
}
@@ -642,7 +662,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.gatewayConflictResolver = gatewayConflictResolver;
}
protected GatewayConflictResolver gatewayConflictResolver() {
protected GatewayConflictResolver getGatewayConflictResolver() {
return this.gatewayConflictResolver;
}
@@ -651,7 +671,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.jndiDataSources = jndiDataSources;
}
protected List<CacheFactoryBean.JndiDataSource> jndiDataSources() {
protected List<CacheFactoryBean.JndiDataSource> getJndiDataSources() {
return nullSafeList(this.jndiDataSources);
}
@@ -706,7 +726,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.pdxDiskStoreName = pdxDiskStoreName;
}
protected String pdxDiskStoreName() {
protected String getPdxDiskStoreName() {
return this.pdxDiskStoreName;
}
@@ -715,7 +735,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.pdxIgnoreUnreadFields = pdxIgnoreUnreadFields;
}
protected Boolean pdxIgnoreUnreadFields() {
protected Boolean getPdxIgnoreUnreadFields() {
return this.pdxIgnoreUnreadFields;
}
@@ -724,7 +744,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.pdxPersistent = pdxPersistent;
}
protected Boolean pdxPersistent() {
protected Boolean getPdxPersistent() {
return this.pdxPersistent;
}
@@ -733,7 +753,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.pdxReadSerialized = pdxReadSerialized;
}
protected Boolean pdxReadSerialized() {
protected Boolean getPdxReadSerialized() {
return this.pdxReadSerialized;
}
@@ -742,7 +762,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.pdxSerializer = pdxSerializer;
}
protected PdxSerializer pdxSerializer() {
protected PdxSerializer getPdxSerializer() {
return this.pdxSerializer;
}
@@ -760,7 +780,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.transactionListeners = transactionListeners;
}
protected List<TransactionListener> transactionListeners() {
protected List<TransactionListener> getTransactionListeners() {
return nullSafeList(this.transactionListeners);
}
@@ -769,7 +789,7 @@ public abstract class AbstractCacheConfiguration extends AbstractAnnotationConfi
this.transactionWriter = transactionWriter;
}
protected TransactionWriter transactionWriter() {
protected TransactionWriter getTransactionWriter() {
return this.transactionWriter;
}

View File

@@ -25,9 +25,6 @@ import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -38,8 +35,10 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport;
import org.springframework.data.gemfire.config.xml.GemfireConstants;
import org.springframework.data.gemfire.server.CacheServerFactoryBean;
import org.springframework.data.gemfire.server.SubscriptionEvictionPolicy;
import org.springframework.util.StringUtils;
/**
@@ -50,9 +49,7 @@ import org.springframework.util.StringUtils;
* @author John Blum
* @see org.apache.geode.cache.server.CacheServer
* @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.BeanDefinitionHolder
* @see org.springframework.beans.factory.support.BeanDefinitionBuilder
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
@@ -63,12 +60,12 @@ import org.springframework.util.StringUtils;
* @see org.springframework.data.gemfire.config.annotation.CacheServerConfigurer
* @see org.springframework.data.gemfire.config.annotation.EnableCacheServers
* @see org.springframework.data.gemfire.config.annotation.EnableCacheServer
* @see org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport
* @see org.springframework.data.gemfire.server.CacheServerFactoryBean
* @since 1.9.0
*/
public class AddCacheServerConfiguration implements BeanFactoryAware, ImportBeanDefinitionRegistrar {
private BeanFactory beanFactory;
public class AddCacheServerConfiguration extends AbstractAnnotationConfigSupport
implements ImportBeanDefinitionRegistrar {
@Autowired(required = false)
private List<CacheServerConfigurer> cacheServerConfigurers = Collections.emptyList();
@@ -104,25 +101,86 @@ public class AddCacheServerConfiguration implements BeanFactoryAware, ImportBean
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CacheServerFactoryBean.class);
String beanName = registerCacheServerFactoryBeanDefinition(builder.getBeanDefinition(),
(String) enableCacheServerAttributes.get("name"), registry);
builder.addPropertyReference("cache", GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME);
builder.addPropertyValue("cacheServerConfigurers", resolveCacheServerConfigurers());
builder.addPropertyValue("autoStartup", enableCacheServerAttributes.get("autoStartup"));
builder.addPropertyValue("bindAddress", enableCacheServerAttributes.get("bindAddress"));
builder.addPropertyValue("hostNameForClients", enableCacheServerAttributes.get("hostnameForClients"));
builder.addPropertyValue("loadPollInterval", enableCacheServerAttributes.get("loadPollInterval"));
builder.addPropertyValue("maxConnections", enableCacheServerAttributes.get("maxConnections"));
builder.addPropertyValue("maxMessageCount", enableCacheServerAttributes.get("maxMessageCount"));
builder.addPropertyValue("maxThreads", enableCacheServerAttributes.get("maxThreads"));
builder.addPropertyValue("maxTimeBetweenPings", enableCacheServerAttributes.get("maxTimeBetweenPings"));
builder.addPropertyValue("messageTimeToLive", enableCacheServerAttributes.get("messageTimeToLive"));
builder.addPropertyValue("port", enableCacheServerAttributes.get("port"));
builder.addPropertyValue("socketBufferSize", enableCacheServerAttributes.get("socketBufferSize"));
builder.addPropertyValue("subscriptionCapacity", enableCacheServerAttributes.get("subscriptionCapacity"));
builder.addPropertyValue("subscriptionDiskStore", enableCacheServerAttributes.get("subscriptionDiskStoreName"));
builder.addPropertyValue("subscriptionEvictionPolicy", enableCacheServerAttributes.get("subscriptionEvictionPolicy"));
registerCacheServerFactoryBeanDefinition(builder.getBeanDefinition(),
(String) enableCacheServerAttributes.get("name"), registry);
builder.addPropertyValue("autoStartup",
resolveProperty(namedCacheServerProperty(beanName, "auto-startup"),
resolveProperty(cacheServerProperty("auto-startup"),
(Boolean) enableCacheServerAttributes.get("autoStartup"))));
builder.addPropertyValue("bindAddress",
resolveProperty(namedCacheServerProperty(beanName, "bind-address"),
resolveProperty(cacheServerProperty("bind-address"),
(String) enableCacheServerAttributes.get("bindAddress"))));
builder.addPropertyValue("hostNameForClients",
resolveProperty(namedCacheServerProperty(beanName, "hostname-for-clients"),
resolveProperty(cacheServerProperty("hostname-for-clients"),
(String) enableCacheServerAttributes.get("hostnameForClients"))));
builder.addPropertyValue("loadPollInterval",
resolveProperty(namedCacheServerProperty(beanName, "load-poll-interval"),
resolveProperty(cacheServerProperty("load-poll-interval"),
(Long) enableCacheServerAttributes.get("loadPollInterval"))));
builder.addPropertyValue("maxConnections",
resolveProperty(namedCacheServerProperty(beanName, "max-connections"),
resolveProperty(cacheServerProperty("max-connections"),
(Integer) enableCacheServerAttributes.get("maxConnections"))));
builder.addPropertyValue("maxMessageCount",
resolveProperty(namedCacheServerProperty(beanName, "max-message-count"),
resolveProperty(cacheServerProperty("max-message-count"),
(Integer) enableCacheServerAttributes.get("maxMessageCount"))));
builder.addPropertyValue("maxThreads",
resolveProperty(namedCacheServerProperty(beanName, "max-threads"),
resolveProperty(cacheServerProperty("max-threads"),
(Integer) enableCacheServerAttributes.get("maxThreads"))));
builder.addPropertyValue("maxTimeBetweenPings",
resolveProperty(namedCacheServerProperty(beanName, "max-time-between-pings"),
resolveProperty(cacheServerProperty("max-time-between-pings"),
(Integer) enableCacheServerAttributes.get("maxTimeBetweenPings"))));
builder.addPropertyValue("messageTimeToLive",
resolveProperty(namedCacheServerProperty(beanName, "message-time-to-live"),
resolveProperty(cacheServerProperty("message-time-to-live"),
(Integer) enableCacheServerAttributes.get("messageTimeToLive"))));
builder.addPropertyValue("port",
resolveProperty(namedCacheServerProperty(beanName, "port"),
resolveProperty(cacheServerProperty("port"),
(Integer) enableCacheServerAttributes.get("port"))));
builder.addPropertyValue("socketBufferSize",
resolveProperty(namedCacheServerProperty(beanName, "socket-buffer-size"),
resolveProperty(cacheServerProperty("socket-buffer-size"),
(Integer) enableCacheServerAttributes.get("socketBufferSize"))));
builder.addPropertyValue("subscriptionCapacity",
resolveProperty(namedCacheServerProperty(beanName, "subscription-capacity"),
resolveProperty(cacheServerProperty("subscription-capacity"),
(Integer) enableCacheServerAttributes.get("subscriptionCapacity"))));
builder.addPropertyValue("subscriptionDiskStore",
resolveProperty(namedCacheServerProperty(beanName, "subscription-disk-store-name"),
resolveProperty(cacheServerProperty("subscription-disk-store-name"),
(String) enableCacheServerAttributes.get("subscriptionDiskStoreName"))));
builder.addPropertyValue("subscriptionEvictionPolicy",
resolveProperty(namedCacheServerProperty(beanName, "subscription-eviction-policy"),
SubscriptionEvictionPolicy.class, resolveProperty(cacheServerProperty("subscription-eviction-policy"),
SubscriptionEvictionPolicy.class, (SubscriptionEvictionPolicy) enableCacheServerAttributes.get("subscriptionEvictionPolicy"))));
builder.addPropertyValue("tcpNoDelay",
resolveProperty(namedCacheServerProperty(beanName, "tcp-no-delay"),
resolveProperty(cacheServerProperty("tcp-no-delay"),
(Boolean) enableCacheServerAttributes.get("tcpNoDelay"))));
}
/* (non-Javadoc) */
@@ -131,7 +189,7 @@ public class AddCacheServerConfiguration implements BeanFactoryAware, ImportBean
return Optional.ofNullable(this.cacheServerConfigurers)
.filter(cacheServerConfigurers -> !cacheServerConfigurers.isEmpty())
.orElseGet(() ->
Optional.of(this.beanFactory)
Optional.of(this.beanFactory())
.filter(beanFactory -> beanFactory instanceof ListableBeanFactory)
.map(beanFactory -> {
Map<String, CacheServerConfigurer> beansOfType = ((ListableBeanFactory) beanFactory)
@@ -143,16 +201,19 @@ public class AddCacheServerConfiguration implements BeanFactoryAware, ImportBean
);
}
/* (non-Javadoc) */
protected void registerCacheServerFactoryBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName,
protected String registerCacheServerFactoryBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName,
BeanDefinitionRegistry registry) {
if (StringUtils.hasText(beanName)) {
BeanDefinitionReaderUtils.registerBeanDefinition(
newBeanDefinitionHolder(beanDefinition, beanName), registry);
return beanName;
}
else {
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);
return BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);
}
}
@@ -163,7 +224,7 @@ public class AddCacheServerConfiguration implements BeanFactoryAware, ImportBean
/* (non-Javadoc) */
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
protected Class getAnnotationType() {
return EnableCacheServer.class;
}
}

View File

@@ -17,7 +17,10 @@
package org.springframework.data.gemfire.config.annotation;
import static java.util.Arrays.stream;
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.RuntimeExceptionFactory.newIllegalArgumentException;
import java.util.Collections;
import java.util.List;
@@ -25,9 +28,6 @@ import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -37,9 +37,9 @@ import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.GemfireUtils;
import org.springframework.data.gemfire.client.PoolFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport;
import org.springframework.data.gemfire.support.ConnectionEndpoint;
import org.springframework.data.gemfire.support.ConnectionEndpointList;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -50,7 +50,6 @@ import org.springframework.util.StringUtils;
* @author John Blum
* @see org.apache.geode.cache.client.Pool
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.beans.factory.support.BeanDefinitionBuilder
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
@@ -60,11 +59,11 @@ import org.springframework.util.StringUtils;
* @see org.springframework.data.gemfire.config.annotation.PoolConfigurer
* @see org.springframework.data.gemfire.config.annotation.EnablePools
* @see org.springframework.data.gemfire.config.annotation.EnablePool
* @see org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport
* @since 1.9.0
*/
public class AddPoolConfiguration implements BeanFactoryAware, ImportBeanDefinitionRegistrar {
private BeanFactory beanFactory;
public class AddPoolConfiguration extends AbstractAnnotationConfigSupport
implements ImportBeanDefinitionRegistrar {
@Autowired(required = false)
private List<PoolConfigurer> poolConfigurers = Collections.emptyList();
@@ -102,27 +101,99 @@ public class AddPoolConfiguration implements BeanFactoryAware, ImportBeanDefinit
BeanDefinitionBuilder poolFactoryBean = BeanDefinitionBuilder.genericBeanDefinition(PoolFactoryBean.class);
poolFactoryBean.addPropertyValue("freeConnectionTimeout", enablePoolAttributes.get("freeConnectionTimeout"));
poolFactoryBean.addPropertyValue("idleTimeout", enablePoolAttributes.get("idleTimeout"));
poolFactoryBean.addPropertyValue("loadConditioningInterval", enablePoolAttributes.get("loadConditioningInterval"));
poolFactoryBean.addPropertyValue("maxConnections", enablePoolAttributes.get("maxConnections"));
poolFactoryBean.addPropertyValue("minConnections", enablePoolAttributes.get("minConnections"));
poolFactoryBean.addPropertyValue("multiUserAuthentication", enablePoolAttributes.get("multiUserAuthentication"));
poolFactoryBean.addPropertyValue("pingInterval", enablePoolAttributes.get("pingInterval"));
poolFactoryBean.addPropertyValue("poolConfigurers", resolvePoolConfigurers());
poolFactoryBean.addPropertyValue("prSingleHopEnabled", enablePoolAttributes.get("prSingleHopEnabled"));
poolFactoryBean.addPropertyValue("readTimeout", enablePoolAttributes.get("readTimeout"));
poolFactoryBean.addPropertyValue("retryAttempts", enablePoolAttributes.get("retryAttempts"));
poolFactoryBean.addPropertyValue("serverGroup", enablePoolAttributes.get("serverGroup"));
poolFactoryBean.addPropertyValue("socketBufferSize", enablePoolAttributes.get("socketBufferSize"));
poolFactoryBean.addPropertyValue("statisticInterval", enablePoolAttributes.get("statisticInterval"));
poolFactoryBean.addPropertyValue("subscriptionAckInterval", enablePoolAttributes.get("subscriptionAckInterval"));
poolFactoryBean.addPropertyValue("subscriptionEnabled", enablePoolAttributes.get("subscriptionEnabled"));
poolFactoryBean.addPropertyValue("subscriptionMessageTrackingTimeout", enablePoolAttributes.get("subscriptionMessageTrackingTimeout"));
poolFactoryBean.addPropertyValue("subscriptionRedundancy", enablePoolAttributes.get("subscriptionRedundancy"));
poolFactoryBean.addPropertyValue("threadLocalConnections", enablePoolAttributes.get("threadLocalConnections"));
poolFactoryBean.addPropertyValue("freeConnectionTimeout",
resolveProperty(namedPoolProperty(poolName, "free-connection-timeout"),
resolveProperty(poolProperty("free-connection-timeout"),
(Integer) enablePoolAttributes.get("freeConnectionTimeout"))));
configurePoolConnections(enablePoolAttributes, poolFactoryBean);
poolFactoryBean.addPropertyValue("idleTimeout",
resolveProperty(namedPoolProperty(poolName, "idle-timeout"),
resolveProperty(poolProperty("idle-timeout"),
(Long) enablePoolAttributes.get("idleTimeout"))));
poolFactoryBean.addPropertyValue("loadConditioningInterval",
resolveProperty(namedPoolProperty(poolName, "load-conditioning-interval"),
resolveProperty(poolProperty("load-conditioning-interval"),
(Integer) enablePoolAttributes.get("loadConditioningInterval"))));
poolFactoryBean.addPropertyValue("maxConnections",
resolveProperty(namedPoolProperty(poolName, "max-connections"),
resolveProperty(poolProperty("max-connections"),
(Integer) enablePoolAttributes.get("maxConnections"))));
poolFactoryBean.addPropertyValue("minConnections",
resolveProperty(namedPoolProperty(poolName, "min-connections"),
resolveProperty(poolProperty("min-connections"),
(Integer) enablePoolAttributes.get("minConnections"))));
poolFactoryBean.addPropertyValue("multiUserAuthentication",
resolveProperty(namedPoolProperty(poolName, "multi-user-authentication"),
resolveProperty(poolProperty("multi-user-authentication"),
(Boolean) enablePoolAttributes.get("multiUserAuthentication"))));
poolFactoryBean.addPropertyValue("pingInterval",
resolveProperty(namedPoolProperty(poolName, "ping-interval"),
resolveProperty(poolProperty("ping-interval"),
(Long) enablePoolAttributes.get("pingInterval"))));
poolFactoryBean.addPropertyValue("poolConfigurers", resolvePoolConfigurers());
poolFactoryBean.addPropertyValue("prSingleHopEnabled",
resolveProperty(namedPoolProperty(poolName, "pr-single-hop-enabled"),
resolveProperty(poolProperty("pr-single-hop-enabled"),
(Boolean) enablePoolAttributes.get("prSingleHopEnabled"))));
poolFactoryBean.addPropertyValue("readTimeout",
resolveProperty(namedPoolProperty(poolName, "read-timeout"),
resolveProperty(poolProperty("read-timeout"),
(Integer) enablePoolAttributes.get("readTimeout"))));
poolFactoryBean.addPropertyValue("retryAttempts",
resolveProperty(namedPoolProperty(poolName, "retry-attempts"),
resolveProperty(poolProperty("retry-attempts"),
(Integer) enablePoolAttributes.get("retryAttempts"))));
poolFactoryBean.addPropertyValue("serverGroup",
resolveProperty(namedPoolProperty(poolName, "server-group"),
resolveProperty(poolProperty("server-group"),
(String) enablePoolAttributes.get("serverGroup"))));
poolFactoryBean.addPropertyValue("socketBufferSize",
resolveProperty(namedPoolProperty(poolName, "socket-buffer-size"),
resolveProperty(poolProperty("socket-buffer-size"),
(Integer) enablePoolAttributes.get("socketBufferSize"))));
poolFactoryBean.addPropertyValue("statisticInterval",
resolveProperty(namedPoolProperty(poolName, "statistic-interval"),
resolveProperty(poolProperty("statistic-interval"),
(Integer) enablePoolAttributes.get("statisticInterval"))));
poolFactoryBean.addPropertyValue("subscriptionAckInterval",
resolveProperty(namedPoolProperty(poolName, "subscription-ack-interval"),
resolveProperty(poolProperty("subscription-ack-interval"),
(Integer) enablePoolAttributes.get("subscriptionAckInterval"))));
poolFactoryBean.addPropertyValue("subscriptionEnabled",
resolveProperty(namedPoolProperty(poolName, "subscription-enabled"),
resolveProperty(poolProperty("subscription-enabled"),
(Boolean) enablePoolAttributes.get("subscriptionEnabled"))));
poolFactoryBean.addPropertyValue("subscriptionMessageTrackingTimeout",
resolveProperty(namedPoolProperty(poolName, "subscription-message-tracking-timeout"),
resolveProperty(poolProperty("subscription-message-tracking-timeout"),
(Integer) enablePoolAttributes.get("subscriptionMessageTrackingTimeout"))));
poolFactoryBean.addPropertyValue("subscriptionRedundancy",
resolveProperty(namedPoolProperty(poolName, "subscription-redundancy"),
resolveProperty(poolProperty("subscription-redundancy"),
(Integer) enablePoolAttributes.get("subscriptionRedundancy"))));
poolFactoryBean.addPropertyValue("threadLocalConnections",
resolveProperty(namedPoolProperty(poolName, "thread-local-connections"),
resolveProperty(poolProperty("thread-local-connections"),
(Boolean) enablePoolAttributes.get("threadLocalConnections"))));
configurePoolConnections(poolName, enablePoolAttributes, poolFactoryBean);
registry.registerBeanDefinition(poolName, poolFactoryBean.getBeanDefinition());
}
@@ -133,7 +204,7 @@ public class AddPoolConfiguration implements BeanFactoryAware, ImportBeanDefinit
return Optional.ofNullable(this.poolConfigurers)
.filter(poolConfigurers -> !poolConfigurers.isEmpty())
.orElseGet(() ->
Optional.of(this.beanFactory)
Optional.of(this.beanFactory())
.filter(beanFactory -> beanFactory instanceof ListableBeanFactory)
.map(beanFactory -> {
Map<String, PoolConfigurer> beansOfType = ((ListableBeanFactory) beanFactory)
@@ -145,10 +216,12 @@ public class AddPoolConfiguration implements BeanFactoryAware, ImportBeanDefinit
);
}
/* (non-Javadoc) */
protected String getAndValidatePoolName(Map<String, Object> enablePoolAttributes) {
String poolName = (String) enablePoolAttributes.get("name");
Assert.hasText(poolName, "Pool name is required");
return poolName;
return Optional.ofNullable((String) enablePoolAttributes.get("name"))
.filter(StringUtils::hasText)
.orElseThrow(() -> newIllegalArgumentException("Pool name is required"));
}
/**
@@ -161,61 +234,81 @@ public class AddPoolConfiguration implements BeanFactoryAware, ImportBeanDefinit
* @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication
* @see java.util.Map
*/
protected BeanDefinitionBuilder configurePoolConnections(Map<String, Object> enablePoolAttributes,
protected BeanDefinitionBuilder configurePoolConnections(String poolName, Map<String, Object> enablePoolAttributes,
BeanDefinitionBuilder poolFactoryBean) {
configureLocators(enablePoolAttributes, poolFactoryBean);
configureServers(enablePoolAttributes, poolFactoryBean);
configurePoolLocators(poolName, enablePoolAttributes, poolFactoryBean);
configurePoolServers(poolName, enablePoolAttributes, poolFactoryBean);
return poolFactoryBean;
}
protected BeanDefinitionBuilder configureLocators(Map<String, Object> enablePoolAttributes,
/* (non-Javadoc) */
protected BeanDefinitionBuilder configurePoolLocators(String poolName, Map<String, Object> enablePoolAttributes,
BeanDefinitionBuilder poolFactoryBean) {
poolFactoryBean.addPropertyValue("locators", parseConnectionEndpoints(enablePoolAttributes,
"locators", "locatorsString", GemfireUtils.DEFAULT_LOCATOR_PORT));
String locatorsFromProperty = resolveProperty(namedPoolProperty(poolName, "locators"),
resolveProperty(poolProperty("locators"), (String) null));
ConnectionEndpointList locators = Optional.ofNullable(locatorsFromProperty)
.filter(StringUtils::hasText)
.map(it -> ConnectionEndpointList.parse(GemfireUtils.DEFAULT_LOCATOR_PORT, it.split(",")))
.orElseGet(() -> parseConnectionEndpoints(enablePoolAttributes,"locators",
"locatorsString", GemfireUtils.DEFAULT_LOCATOR_PORT));
poolFactoryBean.addPropertyValue("locators", locators);
return poolFactoryBean;
}
protected BeanDefinitionBuilder configureServers(Map<String, Object> enablePoolAttributes,
/* (non-Javadoc) */
protected BeanDefinitionBuilder configurePoolServers(String poolName, Map<String, Object> enablePoolAttributes,
BeanDefinitionBuilder poolFactoryBean) {
poolFactoryBean.addPropertyValue("servers", parseConnectionEndpoints(enablePoolAttributes,
"servers", "serversString", GemfireUtils.DEFAULT_CACHE_SERVER_PORT));
String serversFromProperty = resolveProperty(namedPoolProperty(poolName, "servers"),
resolveProperty("servers", (String) null));
ConnectionEndpointList servers = Optional.ofNullable(serversFromProperty)
.filter(StringUtils::hasText)
.map(it -> ConnectionEndpointList.parse(GemfireUtils.DEFAULT_CACHE_SERVER_PORT, it.split(",")))
.orElseGet(() -> parseConnectionEndpoints(enablePoolAttributes, "servers",
"serversString", GemfireUtils.DEFAULT_CACHE_SERVER_PORT));
poolFactoryBean.addPropertyValue("servers", servers);
return poolFactoryBean;
}
/* (non-Javadoc) */
protected ConnectionEndpointList parseConnectionEndpoints(Map<String, Object> enablePoolAttributes,
String arrayAttributeName, String stringAttributeName, int defaultPort) {
ConnectionEndpointList connectionEndpoints = new ConnectionEndpointList();
AnnotationAttributes[] connectionEndpointsMetaData =
(AnnotationAttributes[]) enablePoolAttributes.get(arrayAttributeName);
for (AnnotationAttributes annotationAttributes : connectionEndpointsMetaData) {
connectionEndpoints.add(newConnectionEndpoint((String) annotationAttributes.get("host"),
(Integer) annotationAttributes.get("port")));
}
ConnectionEndpointList connectionEndpoints = new ConnectionEndpointList();
String hostsPorts = (String) enablePoolAttributes.get(stringAttributeName);
stream(nullSafeArray(connectionEndpointsMetaData, AnnotationAttributes.class))
.forEach(annotationAttributes ->
connectionEndpoints.add(newConnectionEndpoint((String) annotationAttributes.get("host"),
(Integer) annotationAttributes.get("port"))));
if (StringUtils.hasText(hostsPorts)) {
connectionEndpoints.add(ConnectionEndpointList.parse(defaultPort, hostsPorts.split(",")));
}
Optional.ofNullable((String) enablePoolAttributes.get(stringAttributeName))
.filter(StringUtils::hasText)
.ifPresent(hostsPorts ->
connectionEndpoints.add(ConnectionEndpointList.parse(defaultPort, hostsPorts.split(","))));
return connectionEndpoints;
}
/* (non-Javadoc) */
protected ConnectionEndpoint newConnectionEndpoint(String host, Integer port) {
return new ConnectionEndpoint(host, port);
}
/* (non-Javadoc) */
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
protected Class getAnnotationType() {
return EnablePool.class;
}
}

View File

@@ -17,11 +17,15 @@
package org.springframework.data.gemfire.config.annotation;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.internal.security.SecurityService;
@@ -31,7 +35,6 @@ import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
@@ -41,9 +44,12 @@ import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.OrderComparator;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.data.gemfire.GemfireUtils;
import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport;
import org.springframework.data.gemfire.util.CollectionUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
/**
@@ -57,41 +63,60 @@ import org.springframework.util.ReflectionUtils;
* @see org.apache.shiro.mgt.DefaultSecurityManager
* @see org.apache.shiro.realm.Realm
* @see org.apache.shiro.spring.LifecycleBeanPostProcessor
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.beans.factory.ListableBeanFactory
* @see org.springframework.context.annotation.Bean
* @see org.springframework.context.annotation.Condition
* @see org.springframework.context.annotation.Conditional
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.core.type.AnnotationMetadata
* @see org.springframework.data.gemfire.config.annotation.ApacheShiroSecurityConfiguration.ApacheShiroPresentCondition
* @see org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport
* @since 1.9.0
*/
@Configuration
@Conditional(ApacheShiroSecurityConfiguration.ApacheShiroPresentCondition.class)
@SuppressWarnings("unused")
public class ApacheShiroSecurityConfiguration implements BeanFactoryAware {
private ListableBeanFactory beanFactory;
public class ApacheShiroSecurityConfiguration extends AbstractAnnotationConfigSupport {
/**
* @inheritDoc
* Returns the {@link EnableSecurity} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableSecurity} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableSecurity
*/
@Override
protected Class getAnnotationType() {
return EnableSecurity.class;
}
/**
* Sets a reference to the Spring {@link BeanFactory}.
*
* @param beanFactory reference to the Spring {@link BeanFactory}.
* @throws IllegalArgumentException if the Spring {@link BeanFactory} is not
* an instance of {@link ListableBeanFactory}.
* @see org.springframework.beans.factory.BeanFactory
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
Assert.isInstanceOf(ListableBeanFactory.class, beanFactory);
this.beanFactory = (ListableBeanFactory) beanFactory;
super.setBeanFactory(Optional.ofNullable(beanFactory)
.filter(it -> it instanceof ListableBeanFactory)
.orElseThrow(() -> newIllegalArgumentException(
"BeanFactory [%s] must be an instance of ListableBeanFactory",
ObjectUtils.nullSafeClassName(beanFactory))));
}
/**
* Returns a reference to the Spring {@link BeanFactory}.
*
* @return a reference to the Spring {@link BeanFactory}.
* @throws IllegalStateException if the Spring {@link BeanFactory} was not properly initialized.
* @throws IllegalStateException if the Spring {@link BeanFactory} was not set.
* @see org.springframework.beans.factory.BeanFactory
*/
protected ListableBeanFactory getBeanFactory() {
org.apache.shiro.util.Assert.state(this.beanFactory != null, "BeanFactory was not properly initialized");
return this.beanFactory;
protected ListableBeanFactory getListableBeanFactory() {
return (ListableBeanFactory) beanFactory();
}
/**
@@ -138,15 +163,18 @@ public class ApacheShiroSecurityConfiguration implements BeanFactoryAware {
*/
@Bean
public org.apache.shiro.mgt.SecurityManager shiroSecurityManager(GemFireCache gemfireCache) {
org.apache.shiro.mgt.SecurityManager shiroSecurityManager = null;
List<Realm> realms = resolveRealms();
if (!realms.isEmpty()) {
shiroSecurityManager = registerSecurityManager(new DefaultSecurityManager(realms));
if (!enableApacheGeodeSecurity()) {
throw new IllegalStateException("Failed to enable security services in Apache Geode");
throw newIllegalStateException("Failed to enable security services in %s",
GemfireUtils.apacheGeodeProductName());
}
}
@@ -167,8 +195,10 @@ public class ApacheShiroSecurityConfiguration implements BeanFactoryAware {
* @see org.apache.shiro.realm.Realm
*/
protected List<Realm> resolveRealms() {
try {
Map<String, Realm> realmBeans = getBeanFactory().getBeansOfType(Realm.class, false, true);
Map<String, Realm> realmBeans = getListableBeanFactory()
.getBeansOfType(Realm.class, false, true);
List<Realm> realms = new ArrayList<>(CollectionUtils.nullSafeMap(realmBeans).values());
Collections.sort(realms, OrderComparator.INSTANCE);
return realms;
@@ -207,18 +237,21 @@ public class ApacheShiroSecurityConfiguration implements BeanFactoryAware {
* @see org.apache.geode.internal.security.SecurityService#getSecurityService()
*/
protected boolean enableApacheGeodeSecurity() {
SecurityService securityService = SecurityService.getSecurityService();
if (securityService != null) {
String isIntegratedSecurityFieldName = "isIntegratedSecurity";
Field isIntegratedSecurity = ReflectionUtils.findField(securityService.getClass(),
isIntegratedSecurityFieldName, Boolean.class);
isIntegratedSecurity = (isIntegratedSecurity != null ? isIntegratedSecurity
: ReflectionUtils.findField(securityService.getClass(), isIntegratedSecurityFieldName, Boolean.TYPE));
isIntegratedSecurity = Optional.ofNullable(isIntegratedSecurity).orElseGet(() ->
ReflectionUtils.findField(securityService.getClass(), isIntegratedSecurityFieldName, Boolean.TYPE));
if (isIntegratedSecurity != null) {
ReflectionUtils.makeAccessible(isIntegratedSecurity);
ReflectionUtils.setField(isIntegratedSecurity, securityService, Boolean.TRUE);

View File

@@ -20,15 +20,17 @@ package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Properties;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
* The AuthConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
* that applies additional GemFire/Geode configuration by way of GemFire/Geode System properties to configure
* GemFire/Geode Authentication and Authorization framework services.
* The {@link AuthConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} that applies
* additional configuration using Pivotal GemFire/Apache Geode {@link Properties} to configure
* Pivotal GemFire/Apache Geode Authentication and Authorization framework and services.
*
* @author John Blum
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.data.gemfire.config.annotation.EnableAuth
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @see <a href="Security">http://gemfire.docs.pivotal.io/docs-gemfire/managing/security/chapter_overview.html</a>
@@ -53,47 +55,65 @@ public class AuthConfiguration extends EmbeddedServiceConfigurationSupport {
protected static final String SECURITY_PEER_VERIFY_MEMBER_TIMEOUT = "security-peer-verifymember-timeout";
/**
* @inheritDoc
* Returns the {@link EnableAuth} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableAuth} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableAuth
*/
@Override
protected Class getAnnotationType() {
return EnableAuth.class;
}
/**
* @inheritDoc
*/
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
PropertiesBuilder gemfireProperties = PropertiesBuilder.create();
gemfireProperties.setProperty(GEMFIRE_SECURITY_PROPERTY_FILE, annotationAttributes.get("securityPropertiesFile"));
gemfireProperties.setProperty(GEMFIRE_SECURITY_PROPERTY_FILE,
resolveProperty(securityProperty("properties-file"),
(String) annotationAttributes.get("securityPropertiesFile")));
gemfireProperties.setProperty(SECURITY_CLIENT_ACCESSOR, annotationAttributes.get("clientAccessor"));
gemfireProperties.setProperty(SECURITY_CLIENT_ACCESSOR,
resolveProperty(securityProperty("client.accessor"),
(String) annotationAttributes.get("clientAccessor")));
gemfireProperties.setProperty(SECURITY_CLIENT_ACCESSOR_POST_PROCESSOR,
annotationAttributes.get("clientAccessPostOperation"));
resolveProperty(securityProperty("client.accessor-post-processor"),
(String) annotationAttributes.get("clientAccessorPostProcessor")));
gemfireProperties.setProperty(SECURITY_CLIENT_AUTH_INIT,
annotationAttributes.get("clientAuthenticationInitializer"));
resolveProperty(securityProperty("client.authentication-initializer"),
(String) annotationAttributes.get("clientAuthenticationInitializer")));
gemfireProperties.setProperty(SECURITY_CLIENT_AUTHENTICATOR, annotationAttributes.get("clientAuthenticator"));
gemfireProperties.setProperty(SECURITY_CLIENT_AUTHENTICATOR,
resolveProperty(securityProperty("client.authenticator"),
(String) annotationAttributes.get("clientAuthenticator")));
gemfireProperties.setProperty(SECURITY_CLIENT_DIFFIE_HELLMAN_ALGORITHM,
annotationAttributes.get("clientDiffieHellmanAlgorithm"));
resolveProperty(securityProperty("client.diffie-hellman-algorithm"),
(String) annotationAttributes.get("clientDiffieHellmanAlgorithm")));
gemfireProperties.setProperty(SECURITY_PEER_AUTH_INIT,
annotationAttributes.get("peerAuthenticationInitializer"));
resolveProperty(securityProperty("peer.authentication-initializer"),
(String) annotationAttributes.get("peerAuthenticationInitializer")));
gemfireProperties.setProperty(SECURITY_PEER_AUTHENTICATOR, annotationAttributes.get("peerAuthenticator"));
gemfireProperties.setProperty(SECURITY_PEER_AUTHENTICATOR,
resolveProperty(securityProperty("peer.authenticator"),
(String) annotationAttributes.get("peerAuthenticator")));
gemfireProperties.setPropertyIfNotDefault(SECURITY_PEER_VERIFY_MEMBER_TIMEOUT,
annotationAttributes.get("peerVerifyMemberTimeout"), DEFAULT_PEER_VERIFY_MEMBER_TIMEOUT);
resolveProperty(securityProperty("peer.verify-member-timeout"),
(Long) annotationAttributes.get("peerVerifyMemberTimeout")), DEFAULT_PEER_VERIFY_MEMBER_TIMEOUT);
gemfireProperties.setProperty(SECURITY_LOG_FILE, annotationAttributes.get("securityLogFile"));
gemfireProperties.setProperty(SECURITY_LOG_FILE,
resolveProperty(securityProperty("log.file"),
(String) annotationAttributes.get("securityLogFile")));
gemfireProperties.setPropertyIfNotDefault(SECURITY_LOG_LEVEL,
annotationAttributes.get("securityLogLevel"), DEFAULT_SECURITY_LOG_LEVEL);
resolveProperty(securityProperty("log.level"),
(String) annotationAttributes.get("securityLogLevel")), DEFAULT_SECURITY_LOG_LEVEL);
return gemfireProperties.build();
}

View File

@@ -18,22 +18,21 @@
package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport;
import org.springframework.data.gemfire.config.support.AutoRegionLookupBeanPostProcessor;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.ExpressionParser;
@@ -42,7 +41,6 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
import org.springframework.expression.spel.support.StandardTypeLocator;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -56,16 +54,22 @@ import org.springframework.util.StringUtils;
*
* @author John Blum
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.context.EnvironmentAware
* @see org.springframework.beans.factory.support.AbstractBeanDefinition
* @see org.springframework.beans.factory.support.BeanDefinitionBuilder
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.core.env.Environment
* @see org.springframework.core.type.AnnotationMetadata
* @see org.springframework.data.gemfire.config.annotation.EnableAutoRegionLookup
* @see org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport
* @see org.springframework.data.gemfire.config.support.AutoRegionLookupBeanPostProcessor
* @see org.springframework.expression.ExpressionParser
* @since 1.9.0
*/
public class AutoRegionLookupConfiguration implements BeanFactoryAware, EnvironmentAware,
ImportBeanDefinitionRegistrar {
public class AutoRegionLookupConfiguration extends AbstractAnnotationConfigSupport
implements ImportBeanDefinitionRegistrar {
private static final boolean DEFAULT_ENABLED = true;
private static final AtomicBoolean AUTO_REGION_LOOKUP_BEAN_POST_PROCESSOR_REGISTERED = new AtomicBoolean(false);
@@ -75,84 +79,83 @@ public class AutoRegionLookupConfiguration implements BeanFactoryAware, Environm
private StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
/* (non-Javadoc) */
@Override
protected Class getAnnotationType() {
return EnableAutoRegionLookup.class;
}
/**
* {@inheritDoc}
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
super.setBeanFactory(beanFactory);
this.evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
if (beanFactory instanceof ConfigurableBeanFactory) {
ConfigurableBeanFactory configurableBeanFactory = (ConfigurableBeanFactory) beanFactory;
evaluationContext.setTypeLocator(new StandardTypeLocator(configurableBeanFactory.getBeanClassLoader()));
this.evaluationContext.setTypeLocator(new StandardTypeLocator(
configurableBeanFactory.getBeanClassLoader()));
ConversionService conversionService = configurableBeanFactory.getConversionService();
if (conversionService != null) {
evaluationContext.setTypeConverter(new StandardTypeConverter(conversionService));
}
Optional.ofNullable(configurableBeanFactory.getConversionService())
.ifPresent(conversionService ->
this.evaluationContext.setTypeConverter(new StandardTypeConverter(conversionService)));
}
}
/**
* {@inheritDoc}
*/
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* Returns a reference to the configured {@link Environment} in the Spring application context.
*
* @return a reference to the configured {@link Environment}.
* @throws IllegalStateException if the {@link Environment} reference was not properly configured.
* @see org.springframework.core.env.Environment
*/
protected Environment getEnvironment() {
Assert.state(environment != null, "The Environment was not properly configured");
return this.environment;
}
/**
* {@inheritDoc}
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
Map<String, Object> enableAutoRegionLookupAttributes =
importingClassMetadata.getAnnotationAttributes(EnableAutoRegionLookup.class.getName());
String enabled = (String) enableAutoRegionLookupAttributes.get("enabled");
if (isEnabled(enabled)) {
registerAutoRegionLookupBeanPostProcessor(registry);
}
Optional.ofNullable(resolveProperty(propertyName("enable-auto-region-lookup"),
(Boolean) enableAutoRegionLookupAttributes.get("enabled")))
.filter(Boolean.TRUE::equals)
.ifPresent(enabled -> registerAutoRegionLookupBeanPostProcessor(registry));
}
/* (non-Javadoc) */
/**
* (non-Javadoc)
*
* This method was used to support Spring property placeholders and SpEL Expressions
* in the {@link EnableAutoRegionLookup#enabled()} attribute. However, this required the attribute to be
* of type {@link String}, which violates type-safety. We are favoring type-safety over configuration
* flexibility and offering alternative means to achieve flexible and dynamic configuration, e.g. properties
* from an {@literal application.properties} file.
*/
private boolean isEnabled(String enabled) {
enabled = StringUtils.trimWhitespace(enabled);
if (!Boolean.parseBoolean(enabled)) {
try {
// try parsing as a SpEL expression...
return spelParser.parseExpression(enabled).getValue(evaluationContext, Boolean.TYPE);
return this.spelParser.parseExpression(enabled).getValue(this.evaluationContext, Boolean.TYPE);
}
catch (EvaluationException ignore) {
return false;
}
catch (ParseException ignore) {
// try resolving as a Spring property placeholder expression...
return getEnvironment().getProperty(enabled, Boolean.TYPE, false);
return environment().getProperty(enabled, Boolean.TYPE, false);
}
}
return true;
return DEFAULT_ENABLED;
}
/* (non-Javadoc) */
private void registerAutoRegionLookupBeanPostProcessor(BeanDefinitionRegistry registry) {
if (AUTO_REGION_LOOKUP_BEAN_POST_PROCESSOR_REGISTERED.compareAndSet(false, true)) {
AbstractBeanDefinition autoRegionLookupBeanPostProcessor = BeanDefinitionBuilder
.rootBeanDefinition(AutoRegionLookupBeanPostProcessor.class)

View File

@@ -40,14 +40,15 @@ import org.springframework.data.gemfire.server.SubscriptionEvictionPolicy;
* and therefore will be configured, constructed and initialized as a Spring bean in the application context.
*
* @author John Blum
* @see org.apache.geode.cache.control.ResourceManager
* @see org.apache.geode.cache.server.CacheServer
* @see org.apache.geode.cache.server.ClientSubscriptionConfig
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.CacheServerConfiguration
* @see org.springframework.data.gemfire.config.annotation.EnableCacheServers
* @see org.springframework.data.gemfire.config.annotation.EnableCacheServer
* @see org.apache.geode.cache.control.ResourceManager
* @see org.apache.geode.cache.server.CacheServer
* @see org.apache.geode.cache.server.ClientSubscriptionConfig
* @since 1.9.0
*/
@Target(ElementType.TYPE)
@@ -62,28 +63,36 @@ public @interface CacheServerApplication {
/**
* Configures whether the {@link CacheServer} should start automatically at runtime.
*
* Default is {@literal true).
* Defaults to {@literal true).
*
* Use {@literal spring.data.gemfire.cache.server.auto-startup} property in {@literal application.properties}.
*/
boolean autoStartup() default true;
/**
* Configures the ip address or host name that this cache server will listen on.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_BIND_ADDRESS
* Defaults to {@link CacheServer#DEFAULT_BIND_ADDRESS}.
*
* Use {@literal spring.data.gemfire.cache.server.bind-address} property in {@literal application.properties}.
*/
String bindAddress() default CacheServer.DEFAULT_BIND_ADDRESS;
/**
* Indicates whether the "copy on read" is enabled for this cache.
*
* Default is {@literal false}.
* Defaults to {@literal false}.
*
* Use {@literal spring.data.gemfire.cache.copy-on-read} property in {@literal application.properties}.
*/
boolean copyOnRead() default false;
/**
* Configures the percentage of heap at or above which the cache is considered in danger of becoming inoperable.
*
* @see org.apache.geode.cache.control.ResourceManager#DEFAULT_CRITICAL_PERCENTAGE
* Defaults to {@link ResourceManager#DEFAULT_CRITICAL_PERCENTAGE}.
*
* Use {@literal spring.data.gemfire.cache.critical-heap-percentage} property in {@literal application.properties}.
*/
float criticalHeapPercentage() default ResourceManager.DEFAULT_CRITICAL_PERCENTAGE;
@@ -92,7 +101,10 @@ public @interface CacheServerApplication {
* after it has been forced out of the distributed system by a network partition event or has otherwise been
* shunned by other members. Use this property to enable the auto-reconnect behavior.
*
* Default is {@literal false}.
* Defaults to {@literal false}.
*
* Use {@literal spring.data.gemfire.cache.peer.enable-auto-reconnect} property
* in {@literal application.properties}.
*/
boolean enableAutoReconnect() default false;
@@ -100,7 +112,9 @@ public @interface CacheServerApplication {
* Configures the percentage of heap at or above which the eviction should begin on Regions configured
* for HeapLRU eviction.
*
* @see org.apache.geode.cache.control.ResourceManager#DEFAULT_EVICTION_PERCENTAGE
* Defaults to {@link ResourceManager#DEFAULT_EVICTION_PERCENTAGE}.
*
* Use {@literal spring.data.gemfire.cache.eviction-heap-percentage} property in {@literal application.properties}.
*/
float evictionHeapPercentage() default ResourceManager.DEFAULT_EVICTION_PERCENTAGE;
@@ -108,69 +122,90 @@ public @interface CacheServerApplication {
* Configures the ip address or host name that server locators will tell clients that this cache server
* is listening on.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_HOSTNAME_FOR_CLIENTS
* Defaults to {@link CacheServer#DEFAULT_HOSTNAME_FOR_CLIENTS}.
*
* Use {@literal spring.data.gemfire.cache.server.hostname-for-clients} property
* in {@literal application.properties}.
*/
String hostnameForClients() default CacheServer.DEFAULT_HOSTNAME_FOR_CLIENTS;
/**
* Configures the frequency in milliseconds to poll the load probe on this cache server.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_LOAD_POLL_INTERVAL
* Defaults to {@link CacheServer#DEFAULT_LOAD_POLL_INTERVAL}.
*
* Use {@literal spring.data.gemfire.cache.server.load-poll-interval} property in {@literal application.properties}.
*/
long loadPollInterval() default CacheServer.DEFAULT_LOAD_POLL_INTERVAL;
/**
* Configures the list of GemFire Locators defining the cluster to which this GemFire cache data node
* should connect.
* Configures the list of Locators defining the cluster to which this Spring cache application will connect.
*
* Use {@literal spring.data.gemfire.cache.copy-on-read} property in {@literal application.properties}.
*/
String locators() default "";
/**
* Configures the length, in seconds, of distributed lock leases obtained by this cache.
*
* Default is {@literal 120} seconds.
* Defaults to {@literal 120} seconds.
*
* Use {@literal spring.data.gemfire.cache.peer.lock-lease} property in {@literal application.properties}.
*/
int lockLease() default 120;
/**
* Configures the number of seconds a cache operation will wait to obtain a distributed lock lease.
*
* Default is {@literal 60} seconds
* Defaults to {@literal 60} seconds.
*
* Use {@literal spring.data.gemfire.cache.peer.lock-timeout} property in {@literal application.properties}.
*/
int lockTimeout() default 60;
/**
* Configures the log level used to output log messages at GemFire cache runtime.
*
* Default is {@literal config}.
* Defaults to {@literal config}.
*
* Use {@literal spring.data.gemfire.cache.log-level} property in {@literal application.properties}.
*/
String logLevel() default CacheServerConfiguration.DEFAULT_LOG_LEVEL;
/**
* Configures the maximum allowed client connections.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_MAX_CONNECTIONS
* Defaults to {@link CacheServer#DEFAULT_MAX_CONNECTIONS}.
*
* Use {@literal spring.data.gemfire.cache.server.max-connections} property in {@literal application.properties}.
*/
int maxConnections() default CacheServer.DEFAULT_MAX_CONNECTIONS;
/**
* Configures he maximum number of messages that can be enqueued in a client-queue.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_MAXIMUM_MESSAGE_COUNT
* Defaults to {@link CacheServer#DEFAULT_MAXIMUM_MESSAGE_COUNT}.
*
* Use {@literal spring.data.gemfire.cache.server.max-message-count} property in {@literal application.properties}.
*/
int maxMessageCount() default CacheServer.DEFAULT_MAXIMUM_MESSAGE_COUNT;
/**
* Configures the maximum number of threads allowed in this cache server to service client requests.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_MAX_THREADS
* Defaults to {@link CacheServer#DEFAULT_MAX_THREADS}.
*
* Use {@literal spring.data.gemfire.cache.server.max-threads} property in {@literal application.properties}.
*/
int maxThreads() default CacheServer.DEFAULT_MAX_THREADS;
/**
* Configures the maximum amount of time between client pings.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS
* Defaults to {@link CacheServer#DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS}.
*
* Use {@literal spring.data.gemfire.cache.server.max-time-between-pings} property
* in {@literal application.properties}.
*/
int maxTimeBetweenPings() default CacheServer.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS;
@@ -178,54 +213,74 @@ public @interface CacheServerApplication {
* Configures the frequency (in seconds) at which a message will be sent by the primary cache-server to all
* the secondary cache-server nodes to remove the events which have already been dispatched from the queue.
*
* Default is {@literal 1} second.
* Defaults to {@literal 1} second.
*
* Use {@literal spring.data.gemfire.cache.peer.message-sync-interval} property
* in {@literal application.properties}.
*/
int messageSyncInterval() default 1;
/**
* Configures the time (in seconds ) after which a message in the client queue will expire.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_MESSAGE_TIME_TO_LIVE
* Defaults to {@link CacheServer#DEFAULT_MESSAGE_TIME_TO_LIVE}.
*
* Use {@literal spring.data.gemfire.cache.server.message-time-to-live} property
* in {@literal application.properties}.
*/
int messageTimeToLive() default CacheServer.DEFAULT_MESSAGE_TIME_TO_LIVE;
/**
* Configures the name of this GemFire member in the cluster (distributed system).
*
* Default is {@literal SpringBasedCacheClientApplication}.
* Defaults to {@literal SpringBasedCacheServerApplication}.
*
* Use {@literal spring.data.gemfire.cache.name} property in {@literal application.properties}.
*/
String name() default CacheServerConfiguration.DEFAULT_NAME;
/**
* Configures the port on which this cache server listens for clients.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_PORT
* Defaults to {@link CacheServer#DEFAULT_PORT}.
*
* Use {@literal spring.data.gemfire.cache.server.port} property in {@literal application.properties}.
*/
int port() default CacheServer.DEFAULT_PORT;
/**
* Configures the number of seconds a cache get operation can spend searching for a value before it times out.
*
* Default is {@literal 300} seconds.
* Defaults to {@literal 300} seconds, or 5 minutes.
*
* Use {@literal spring.data.gemfire.cache.peer.search-timeout} property in {@literal application.properties}.
*/
int searchTimeout() default 300;
/**
* Configures the configured buffer size of the socket connection for this CacheServer.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_SOCKET_BUFFER_SIZE
* Defaults to {@link CacheServer#DEFAULT_SOCKET_BUFFER_SIZE}.
*
* Use {@literal spring.data.gemfire.cache.server.socket-buffer-size} property in {@literal application.properties}.
*/
int socketBufferSize() default CacheServer.DEFAULT_SOCKET_BUFFER_SIZE;
/**
* Configures the capacity of the client queue.
*
* @see org.apache.geode.cache.server.ClientSubscriptionConfig#DEFAULT_CAPACITY
* Defaults to {@link ClientSubscriptionConfig#DEFAULT_CAPACITY}.
*
* Use {@literal spring.data.gemfire.cache.server.subscription-capacity} property
* in {@literal application.properties}.
*/
int subscriptionCapacity() default ClientSubscriptionConfig.DEFAULT_CAPACITY;
/**
* Configures the disk store name for overflow.
*
* Use {@literal spring.data.gemfire.cache.server.subscription-disk-store-name} property
* in {@literal application.properties}.
*/
String subscriptionDiskStoreName() default "";
@@ -233,6 +288,9 @@ public @interface CacheServerApplication {
* Configures the eviction policy that is executed when capacity of the client queue is reached.
*
* Defaults to {@link SubscriptionEvictionPolicy#NONE}.
*
* Use {@literal spring.data.gemfire.cache.server.subscription-eviction-policy} property
* in {@literal application.properties}.
*/
SubscriptionEvictionPolicy subscriptionEvictionPolicy() default SubscriptionEvictionPolicy.NONE;
@@ -242,6 +300,8 @@ public @interface CacheServerApplication {
* created in a non-Spring managed, GemFire context.
*
* Defaults to {@literal false}.
*
* Use {@literal spring.data.gemfire.use-bean-factory-locator} property in {@literal application.properties}.
*/
boolean useBeanFactoryLocator() default false;
@@ -249,8 +309,22 @@ public @interface CacheServerApplication {
* Configures whether this GemFire cache member node would pull it's configuration meta-data
* from the cluster-based Cluster Configuration service.
*
* Default is {@literal false}.
* Defaults to {@literal false}.
*
* Use {@literal spring.data.gemfire.cache.peer.use-cluster-configuration} property
* in {@literal application.properties}.
*/
boolean useClusterConfiguration() default false;
/**
* Configures the tcpNoDelay setting of sockets used to send messages to clients.
*
* TcpNoDelay is enabled by default.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.tcp-no-delay} property
* or the {@literal spring.data.gemfire.cache.server.tcp-no-delay} property
* in {@literal application.properties}.
*/
boolean tcpNoDelay() default CacheServer.DEFAULT_TCP_NO_DELAY;
}

View File

@@ -28,11 +28,13 @@ import java.util.Set;
import java.util.stream.Collectors;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.InterestRegistrationListener;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.server.CacheServer;
import org.apache.geode.cache.server.ClientSubscriptionConfig;
import org.apache.geode.cache.server.ServerLoadProbe;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -70,6 +72,8 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
private boolean autoStartup = DEFAULT_AUTO_STARTUP;
private Boolean tcpNoDelay;
private Integer maxConnections;
private Integer maxMessageCount;
private Integer maxThreads;
@@ -105,28 +109,32 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
* @see org.apache.geode.cache.Cache
*/
@Bean
public CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache) {
public CacheServerFactoryBean gemfireCacheServer(GemFireCache gemfireCache) {
Assert.isInstanceOf(Cache.class, gemfireCache,
"GemFireCache must be an instance of org.apache.geode.cache.Cache");
CacheServerFactoryBean gemfireCacheServer = new CacheServerFactoryBean();
gemfireCacheServer.setCache(gemfireCache);
gemfireCacheServer.setCache((Cache) gemfireCache);
gemfireCacheServer.setCacheServerConfigurers(resolveCacheServerConfigurers());
gemfireCacheServer.setAutoStartup(autoStartup());
gemfireCacheServer.setBindAddress(bindAddress());
gemfireCacheServer.setHostNameForClients(hostnameForClients());
gemfireCacheServer.setListeners(interestRegistrationListeners());
gemfireCacheServer.setLoadPollInterval(loadPollInterval());
gemfireCacheServer.setMaxConnections(maxConnections());
gemfireCacheServer.setMaxMessageCount(maxMessageCount());
gemfireCacheServer.setMaxThreads(maxThreads());
gemfireCacheServer.setMaxTimeBetweenPings(maxTimeBetweenPings());
gemfireCacheServer.setMessageTimeToLive(messageTimeToLive());
gemfireCacheServer.setPort(port());
gemfireCacheServer.setServerLoadProbe(serverLoadProbe());
gemfireCacheServer.setSocketBufferSize(socketBufferSize());
gemfireCacheServer.setSubscriptionCapacity(subscriptionCapacity());
gemfireCacheServer.setSubscriptionDiskStore(subscriptionDiskStoreName());
gemfireCacheServer.setSubscriptionEvictionPolicy(subscriptionEvictionPolicy());
gemfireCacheServer.setAutoStartup(isAutoStartup());
gemfireCacheServer.setBindAddress(getBindAddress());
gemfireCacheServer.setHostNameForClients(getHostnameForClients());
gemfireCacheServer.setListeners(getInterestRegistrationListeners());
gemfireCacheServer.setLoadPollInterval(getLoadPollInterval());
gemfireCacheServer.setMaxConnections(getMaxConnections());
gemfireCacheServer.setMaxMessageCount(getMaxMessageCount());
gemfireCacheServer.setMaxThreads(getMaxThreads());
gemfireCacheServer.setMaxTimeBetweenPings(getMaxTimeBetweenPings());
gemfireCacheServer.setMessageTimeToLive(getMessageTimeToLive());
gemfireCacheServer.setPort(getPort());
gemfireCacheServer.setServerLoadProbe(getServerLoadProbe());
gemfireCacheServer.setSocketBufferSize(getSocketBufferSize());
gemfireCacheServer.setSubscriptionCapacity(getSubscriptionCapacity());
gemfireCacheServer.setSubscriptionDiskStore(getSubscriptionDiskStoreName());
gemfireCacheServer.setSubscriptionEvictionPolicy(getSubscriptionEvictionPolicy());
gemfireCacheServer.setTcpNoDelay(getTcpNoDelay());
return gemfireCacheServer;
}
@@ -140,10 +148,12 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
Optional.of(this.beanFactory())
.filter(beanFactory -> beanFactory instanceof ListableBeanFactory)
.map(beanFactory -> {
Map<String, CacheServerConfigurer> beansOfType = ((ListableBeanFactory) beanFactory)
.getBeansOfType(CacheServerConfigurer.class, true, true);
return nullSafeMap(beansOfType).values().stream().collect(Collectors.toList());
})
.orElseGet(Collections::emptyList)
);
@@ -165,24 +175,53 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
if (isCacheServerApplication(importMetadata)) {
Map<String, Object> cacheServerApplicationMetadata =
Map<String, Object> cacheServerApplicationAttributes =
importMetadata.getAnnotationAttributes(getAnnotationTypeName());
setAutoStartup(Boolean.TRUE.equals(cacheServerApplicationMetadata.get("autoStartup")));
setBindAddress((String) cacheServerApplicationMetadata.get("bindAddress"));
setHostnameForClients((String) cacheServerApplicationMetadata.get("hostnameForClients"));
setLoadPollInterval((Long) cacheServerApplicationMetadata.get("loadPollInterval"));
setMaxConnections((Integer) cacheServerApplicationMetadata.get("maxConnections"));
setMaxMessageCount((Integer) cacheServerApplicationMetadata.get("maxMessageCount"));
setMaxThreads((Integer) cacheServerApplicationMetadata.get("maxThreads"));
setMaxTimeBetweenPings((Integer) cacheServerApplicationMetadata.get("maxTimeBetweenPings"));
setMessageTimeToLive((Integer) cacheServerApplicationMetadata.get("messageTimeToLive"));
setPort((Integer) cacheServerApplicationMetadata.get("port"));
setSocketBufferSize((Integer) cacheServerApplicationMetadata.get("socketBufferSize"));
setSubscriptionCapacity((Integer) cacheServerApplicationMetadata.get("subscriptionCapacity"));
setSubscriptionDiskStoreName((String) cacheServerApplicationMetadata.get("subscriptionDiskStoreName"));
setSubscriptionEvictionPolicy((SubscriptionEvictionPolicy)
cacheServerApplicationMetadata.get("subscriptionEvictionPolicy"));
setAutoStartup(resolveProperty(cacheServerProperty("auto-startup"),
Boolean.TRUE.equals(cacheServerApplicationAttributes.get("autoStartup"))));
setBindAddress(resolveProperty(cacheServerProperty("bind-address"),
(String) cacheServerApplicationAttributes.get("bindAddress")));
setHostnameForClients(resolveProperty(cacheServerProperty("hostname-for-clients"),
(String) cacheServerApplicationAttributes.get("hostnameForClients")));
setLoadPollInterval(resolveProperty(cacheServerProperty("load-poll-interval"),
(Long) cacheServerApplicationAttributes.get("loadPollInterval")));
setMaxConnections(resolveProperty(cacheServerProperty("max-connections"),
(Integer) cacheServerApplicationAttributes.get("maxConnections")));
setMaxMessageCount(resolveProperty(cacheServerProperty("max-message-count"),
(Integer) cacheServerApplicationAttributes.get("maxMessageCount")));
setMaxThreads(resolveProperty(cacheServerProperty("max-threads"),
(Integer) cacheServerApplicationAttributes.get("maxThreads")));
setMaxTimeBetweenPings(resolveProperty(cacheServerProperty("max-time-between-pings"),
(Integer) cacheServerApplicationAttributes.get("maxTimeBetweenPings")));
setMessageTimeToLive(resolveProperty(cacheServerProperty("message-time-to-live"),
(Integer) cacheServerApplicationAttributes.get("messageTimeToLive")));
setPort(resolveProperty(cacheServerProperty("port"),
(Integer) cacheServerApplicationAttributes.get("port")));
setSocketBufferSize(resolveProperty(cacheServerProperty("socket-buffer-size"),
(Integer) cacheServerApplicationAttributes.get("socketBufferSize")));
setSubscriptionCapacity(resolveProperty(cacheServerProperty("subscription-capacity"),
(Integer) cacheServerApplicationAttributes.get("subscriptionCapacity")));
setSubscriptionDiskStoreName(resolveProperty(cacheServerProperty("subscription-disk-store-name"),
(String) cacheServerApplicationAttributes.get("subscriptionDiskStoreName")));
setSubscriptionEvictionPolicy(resolveProperty(cacheServerProperty("subscription-eviction-policy"),
SubscriptionEvictionPolicy.class, (SubscriptionEvictionPolicy) cacheServerApplicationAttributes.get("subscriptionEvictionPolicy")));
setTcpNoDelay(resolveProperty(cacheServerProperty("tcpNoDelay"),
(Boolean) cacheServerApplicationAttributes.get("tcpNoDelay")));
}
}
@@ -199,7 +238,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.autoStartup = autoStartup;
}
protected boolean autoStartup() {
protected boolean isAutoStartup() {
return this.autoStartup;
}
@@ -208,7 +247,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.bindAddress = bindAddress;
}
protected String bindAddress() {
protected String getBindAddress() {
return Optional.ofNullable(this.bindAddress).filter(StringUtils::hasText)
.orElse(CacheServer.DEFAULT_BIND_ADDRESS);
}
@@ -218,7 +257,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.hostnameForClients = hostnameForClients;
}
protected String hostnameForClients() {
protected String getHostnameForClients() {
return Optional.ofNullable(this.hostnameForClients).filter(StringUtils::hasText)
.orElse(CacheServer.DEFAULT_HOSTNAME_FOR_CLIENTS);
}
@@ -228,7 +267,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.interestRegistrationListeners = interestRegistrationListeners;
}
protected Set<InterestRegistrationListener> interestRegistrationListeners() {
protected Set<InterestRegistrationListener> getInterestRegistrationListeners() {
return nullSafeSet(this.interestRegistrationListeners);
}
@@ -237,7 +276,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.loadPollInterval = loadPollInterval;
}
protected Long loadPollInterval() {
protected Long getLoadPollInterval() {
return Optional.ofNullable(this.loadPollInterval).orElse(CacheServer.DEFAULT_LOAD_POLL_INTERVAL);
}
@@ -246,7 +285,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.maxConnections = maxConnections;
}
protected Integer maxConnections() {
protected Integer getMaxConnections() {
return Optional.ofNullable(this.maxConnections).orElse(CacheServer.DEFAULT_MAX_CONNECTIONS);
}
@@ -255,7 +294,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.maxMessageCount = maxMessageCount;
}
protected Integer maxMessageCount() {
protected Integer getMaxMessageCount() {
return Optional.ofNullable(this.maxMessageCount).orElse(CacheServer.DEFAULT_MAXIMUM_MESSAGE_COUNT);
}
@@ -264,7 +303,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.maxThreads = maxThreads;
}
protected Integer maxThreads() {
protected Integer getMaxThreads() {
return Optional.ofNullable(this.maxThreads).orElse(CacheServer.DEFAULT_MAX_THREADS);
}
@@ -273,7 +312,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.maxTimeBetweenPings = maxTimeBetweenPings;
}
protected Integer maxTimeBetweenPings() {
protected Integer getMaxTimeBetweenPings() {
return Optional.ofNullable(this.maxTimeBetweenPings).orElse(CacheServer.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS);
}
@@ -282,7 +321,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.messageTimeToLive = messageTimeToLive;
}
protected Integer messageTimeToLive() {
protected Integer getMessageTimeToLive() {
return Optional.ofNullable(this.messageTimeToLive).orElse(CacheServer.DEFAULT_MESSAGE_TIME_TO_LIVE);
}
@@ -291,7 +330,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.port = port;
}
protected Integer port() {
protected Integer getPort() {
return Optional.ofNullable(this.port).orElse(CacheServer.DEFAULT_PORT);
}
@@ -300,7 +339,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.serverLoadProbe = serverLoadProbe;
}
protected ServerLoadProbe serverLoadProbe() {
protected ServerLoadProbe getServerLoadProbe() {
return Optional.ofNullable(this.serverLoadProbe).orElse(CacheServer.DEFAULT_LOAD_PROBE);
}
@@ -309,7 +348,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.socketBufferSize = socketBufferSize;
}
protected Integer socketBufferSize() {
protected Integer getSocketBufferSize() {
return Optional.ofNullable(this.socketBufferSize).orElse(CacheServer.DEFAULT_SOCKET_BUFFER_SIZE);
}
@@ -318,7 +357,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.subscriptionCapacity = subscriptionCapacity;
}
protected Integer subscriptionCapacity() {
protected Integer getSubscriptionCapacity() {
return Optional.ofNullable(this.subscriptionCapacity).orElse(ClientSubscriptionConfig.DEFAULT_CAPACITY);
}
@@ -327,7 +366,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.subscriptionDiskStoreName = subscriptionDiskStoreName;
}
protected String subscriptionDiskStoreName() {
protected String getSubscriptionDiskStoreName() {
return this.subscriptionDiskStoreName;
}
@@ -336,10 +375,19 @@ public class CacheServerConfiguration extends PeerCacheConfiguration {
this.subscriptionEvictionPolicy = subscriptionEvictionPolicy;
}
protected SubscriptionEvictionPolicy subscriptionEvictionPolicy() {
protected SubscriptionEvictionPolicy getSubscriptionEvictionPolicy() {
return Optional.ofNullable(this.subscriptionEvictionPolicy).orElse(SubscriptionEvictionPolicy.DEFAULT);
}
/* (non-Javadoc) */
void setTcpNoDelay(Boolean tcpNoDelay) {
this.tcpNoDelay = tcpNoDelay;
}
protected Boolean getTcpNoDelay() {
return Optional.ofNullable(this.tcpNoDelay).orElse(CacheServer.DEFAULT_TCP_NO_DELAY);
}
@Override
public String toString() {
return DEFAULT_NAME;

View File

@@ -56,14 +56,18 @@ public @interface ClientCacheApplication {
/**
* Indicates whether the "copy on read" is enabled for this cache.
*
* Default is {@literal false}.
* Defaults to {@literal false}.
*
* Use {@literal spring.data.gemfire.cache.copy-on-read} property in {@literal application.properties}.
*/
boolean copyOnRead() default false;
/**
* Configures the percentage of heap at or above which the cache is considered in danger of becoming inoperable.
*
* @see org.apache.geode.cache.control.ResourceManager#DEFAULT_CRITICAL_PERCENTAGE
* Defaults to {@link ResourceManager#DEFAULT_CRITICAL_PERCENTAGE}.
*
* Use {@literal spring.data.gemfire.cache.critical-heap-percentage} property in {@literal application.properties}.
*/
float criticalHeapPercentage() default ResourceManager.DEFAULT_CRITICAL_PERCENTAGE;
@@ -71,12 +75,19 @@ public @interface ClientCacheApplication {
* Used only for clients in a client/server installation. If set, this indicates that the client is durable
* and identifies the client. The ID is used by servers to reestablish any messaging that was interrupted
* by client downtime.
*
* Use {@literal spring.data.gemfire.cache.client.durable-client-id} property in {@literal application.properties}.
*/
String durableClientId() default "";
/**
* Used only for clients in a client/server installation. Number of seconds this client can remain disconnected
* from its server and have the server continue to accumulate durable events for it.
*
* Defaults to {@literal 300} seconds, or 5 minutes.
*
* Use {@literal spring.data.gemfire.cache.client.durable-client-timeout} property
* in {@literal application.properties}.
*/
int durableClientTimeout() default 300;
@@ -84,83 +95,117 @@ public @interface ClientCacheApplication {
* Configures the percentage of heap at or above which the eviction should begin on Regions configured
* for HeapLRU eviction.
*
* @see org.apache.geode.cache.control.ResourceManager#DEFAULT_EVICTION_PERCENTAGE
* Defaults to {@link ResourceManager#DEFAULT_EVICTION_PERCENTAGE}.
*
* Use {@literal spring.data.gemfire.cache.eviction-heap-percentage} property in {@literal application.properties}.
*/
float evictionHeapPercentage() default ResourceManager.DEFAULT_EVICTION_PERCENTAGE;
/**
* Configures the free connection timeout for this pool.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_FREE_CONNECTION_TIMEOUT
* Defaults to {@link PoolFactory#DEFAULT_FREE_CONNECTION_TIMEOUT}.
*
* Use either the {@literal spring.data.gemfire.pool.default.free-connection-timeout} property
* or the {@literal spring.data.gemfire.pool.free-connection-timeout} property in {@literal application.properties}.
*/
int freeConnectionTimeout() default PoolFactory.DEFAULT_FREE_CONNECTION_TIMEOUT;
/**
* Configures the amount of time a connection can be idle before expiring the connection.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_IDLE_TIMEOUT
* Defaults to {@link PoolFactory#DEFAULT_IDLE_TIMEOUT}.
*
* Use either the {@literal spring.data.gemfire.pool.default.idle-timeout} property
* or the {@literal spring.data.gemfire.pool.idle-timeout} property in {@literal application.properties}.
*/
long idleTimeout() default PoolFactory.DEFAULT_IDLE_TIMEOUT;
/**
* Configures whether to keep the client queues alive on the server when the client is disconnected
*
* Default is {@literal false}.
* Defaults to {@literal false}.
*
* Use {@literal spring.data.gemfire.cache.client.keep-alive} property in {@literal application.properties}.
*/
boolean keepAlive() default false;
/**
* Configures the load conditioning interval for this pool.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_LOAD_CONDITIONING_INTERVAL
* Defaults to {@link PoolFactory#DEFAULT_LOAD_CONDITIONING_INTERVAL}.
*
* Use either the {@literal spring.data.gemfire.pool.default.load-conditioning-interval} property
* or the {@literal spring.data.gemfire.pool.load-conditioning-interval} property
* in {@literal application.properties}.
*/
int loadConditioningInterval() default PoolFactory.DEFAULT_LOAD_CONDITIONING_INTERVAL;
/**
* Configures the GemFire {@link org.apache.geode.distributed.Locator}s to which
* Configures the GemFire {@link org.apache.geode.distributed.Locator Locators} to which
* this cache client will connect.
*
* Use either the {@literal spring.data.gemfire.pool.default.locators} property
* or the {@literal spring.data.gemfire.pool.locators} property in {@literal application.properties}.
*/
Locator[] locators() default {};
/**
* Configures the log level used to output log messages at GemFire cache runtime.
*
* Default is {@literal config}.
* Defaults to {@literal config}.
*
* Use {@literal spring.data.gemfire.cache.log-level} property in {@literal application.properties}.
*/
String logLevel() default ClientCacheConfiguration.DEFAULT_LOG_LEVEL;
/**
* Configures the max number of client to server connections that the pool will create.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_MAX_CONNECTIONS
* Defaults to {@link PoolFactory#DEFAULT_MAX_CONNECTIONS}.
*
* Use either the {@literal spring.data.gemfire.pool.default.max-connections} property
* or the {@literal spring.data.gemfire.pool.max-connections} property in {@literal application.properties}.
*/
int maxConnections() default PoolFactory.DEFAULT_MAX_CONNECTIONS;
/**
* Configures the minimum number of connections to keep available at all times.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_MIN_CONNECTIONS
* Defaults to {@link PoolFactory#DEFAULT_MIN_CONNECTIONS}.
*
* Use either the {@literal spring.data.gemfire.pool.default.min-connections} property
* or the {@literal spring.data.gemfire.pool.min-connections} property in {@literal application.properties}.
*/
int minConnections() default PoolFactory.DEFAULT_MIN_CONNECTIONS;
/**
* If set to true then the created pool can be used by multiple users.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_MULTIUSER_AUTHENTICATION
* Defaults to {@link PoolFactory#DEFAULT_MULTIUSER_AUTHENTICATION}.
*
* Use either the {@literal spring.data.gemfire.pool.default.multi-user-authentication} property
* or the {@literal spring.data.gemfire.pool.multi-user-authentication} property
* in {@literal application.properties}.
*/
boolean multiUserAuthentication() default PoolFactory.DEFAULT_MULTIUSER_AUTHENTICATION;
/**
* Configures the name of this GemFire member in the cluster (distributed system).
*
* Default is {@literal SpringBasedCacheClientApplication}.
* Defaults to {@literal SpringBasedCacheClientApplication}.
*
* Use {@literal spring.data.gemfire.cache.name} property in {@literal application.properties}.
*/
String name() default ClientCacheConfiguration.DEFAULT_NAME;
/**
* Configures how often to ping servers to verify that they are still alive.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_PING_INTERVAL
* Defaults to {@link PoolFactory#DEFAULT_PING_INTERVAL}.
*
* Use either the {@literal spring.data.gemfire.pool.default.ping-interval} property
* or the {@literal spring.data.gemfire.pool.ping-interval} property in {@literal application.properties}.
*/
long pingInterval() default PoolFactory.DEFAULT_PING_INTERVAL;
@@ -168,7 +213,10 @@ public @interface ClientCacheApplication {
* By default {@code prSingleHopEnabled} is {@literal true} in which case the client is aware of the location
* of partitions on servers hosting Regions with {@link org.apache.geode.cache.DataPolicy#PARTITION}.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_PR_SINGLE_HOP_ENABLED
* Defaults to {@link PoolFactory#DEFAULT_PR_SINGLE_HOP_ENABLED}.
*
* Use either the {@literal spring.data.gemfire.pool.default.pr-single-hop-enabled} property
* or the {@literal spring.data.gemfire.pool.pr-single-hop-enabled} property in {@literal application.properties}.
*/
boolean prSingleHopEnabled() default PoolFactory.DEFAULT_PR_SINGLE_HOP_ENABLED;
@@ -176,48 +224,69 @@ public @interface ClientCacheApplication {
* Configures the number of milliseconds to wait for a response from a server before timing out the operation
* and trying another server (if any are available).
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_READ_TIMEOUT
* Defaults to {@link PoolFactory#DEFAULT_READ_TIMEOUT}.
*
* Use either the {@literal spring.data.gemfire.pool.default.read-timeout} property
* or the {@literal spring.data.gemfire.pool.read-timeout} property in {@literal application.properties}.
*/
int readTimeout() default PoolFactory.DEFAULT_READ_TIMEOUT;
/**
* Notifies the server that this durable client is ready to receive updates.
*
* Default is {@literal false}.
* Defaults to {@literal false}.
*
* Use either the {@literal spring.data.gemfire.pool.default.ready-for-events} property
* or the {@literal spring.data.gemfire.pool.ready-for-events} property in {@literal application.properties}.
*/
boolean readyForEvents() default false;
/**
* Configures the number of times to retry a request after timeout/exception.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_RETRY_ATTEMPTS
* Defaults to {@link PoolFactory#DEFAULT_RETRY_ATTEMPTS}.
*
* Use either the {@literal spring.data.gemfire.pool.default.retry-attempts} property
* or the {@literal spring.data.gemfire.pool.retry-attempts} property in {@literal application.properties}.
*/
int retryAttempts() default PoolFactory.DEFAULT_RETRY_ATTEMPTS;
/**
* Configures the group that all servers in which this pool connects to must belong to.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SERVER_GROUP
* Defaults to {@link PoolFactory#DEFAULT_SERVER_GROUP}.
*
* Use either the {@literal spring.data.gemfire.pool.default.server-group} property
* or the {@literal spring.data.gemfire.pool.server-group} property in {@literal application.properties}.
*/
String serverGroup() default PoolFactory.DEFAULT_SERVER_GROUP;
/**
* Configures the GemFire {@link org.apache.geode.cache.server.CacheServer}s to which
* Configures the GemFire {@link org.apache.geode.cache.server.CacheServer CacheServers} to which
* this cache client will connect.
*
* Use either the {@literal spring.data.gemfire.pool.default.servers} property
* or the {@literal spring.data.gemfire.pool.servers} property in {@literal application.properties}.
*/
Server[] servers() default {};
/**
* Configures the socket buffer size for each connection made in this pool.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SOCKET_BUFFER_SIZE
* Defaults to {@link PoolFactory#DEFAULT_SOCKET_BUFFER_SIZE}.
*
* Use either the {@literal spring.data.gemfire.pool.default.socket-buffer-size} property
* or the {@literal spring.data.gemfire.pool.socket-buffer-size} property in {@literal application.properties}.
*/
int socketBufferSize() default PoolFactory.DEFAULT_SOCKET_BUFFER_SIZE;
/**
* Configures how often to send client statistics to the server.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_STATISTIC_INTERVAL
* Defaults to {@link PoolFactory#DEFAULT_STATISTIC_INTERVAL}.
*
* Use either the {@literal spring.data.gemfire.pool.default.statistic-interval} property
* or the {@literal spring.data.gemfire.pool.statistic-interval} property in {@literal application.properties}.
*/
int statisticInterval() default PoolFactory.DEFAULT_STATISTIC_INTERVAL;
@@ -225,14 +294,21 @@ public @interface ClientCacheApplication {
* Configures the interval in milliseconds to wait before sending acknowledgements to the cache server
* for events received from the server subscriptions.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_ACK_INTERVAL
* Defaults to {@link PoolFactory#DEFAULT_SUBSCRIPTION_ACK_INTERVAL}.
*
* Use either the {@literal spring.data.gemfire.pool.default.subscription-ack-interval} property
* or the {@literal spring.data.gemfire.pool.subscription-ack-interval} property
* in {@literal application.properties}.
*/
int subscriptionAckInterval() default PoolFactory.DEFAULT_SUBSCRIPTION_ACK_INTERVAL;
/**
* If set to true then the created pool will have server-to-client subscriptions enabled.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_ENABLED
* Defaults to {@link PoolFactory#DEFAULT_SUBSCRIPTION_ENABLED}.
*
* Use either the {@literal spring.data.gemfire.pool.default.subscription-enabled} property
* or the {@literal spring.data.gemfire.pool.subscription-enabled} property in {@literal application.properties}.
*/
boolean subscriptionEnabled() default PoolFactory.DEFAULT_SUBSCRIPTION_ENABLED;
@@ -240,21 +316,32 @@ public @interface ClientCacheApplication {
* Configures the messageTrackingTimeout attribute which is the time-to-live period, in milliseconds,
* for subscription events the client has received from the server.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT
* Defaults to {@link PoolFactory#DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT}.
*
* Use either the {@literal spring.data.gemfire.pool.default.subscription-message-tracking-timeout} property
* or the {@literal spring.data.gemfire.pool.subscription-message-tracking-timeout} property
* in {@literal application.properties}.
*/
int subscriptionMessageTrackingTimeout() default PoolFactory.DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT;
/**
* Configures the redundancy level for this pools server-to-client subscriptions.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_REDUNDANCY
* Defaults to {@link PoolFactory#DEFAULT_SUBSCRIPTION_REDUNDANCY}.
*
* Use either the {@literal spring.data.gemfire.pool.default.subscription-redundancy} property
* or the {@literal spring.data.gemfire.pool.subscription-redundancy} property in {@literal application.properties}.
*/
int subscriptionRedundancy() default PoolFactory.DEFAULT_SUBSCRIPTION_REDUNDANCY;
/**
* Configures the thread local connections policy for this pool.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_THREAD_LOCAL_CONNECTIONS
* Defaults to {@link PoolFactory#DEFAULT_THREAD_LOCAL_CONNECTIONS}.
*
* Use either the {@literal spring.data.gemfire.pool.default.thread-local-connections} property
* or the {@literal spring.data.gemfire.pool.thread-local-connections} property
* in {@literal application.properties}.
*/
boolean threadLocalConnections() default PoolFactory.DEFAULT_THREAD_LOCAL_CONNECTIONS;
@@ -264,6 +351,8 @@ public @interface ClientCacheApplication {
* created in a non-Spring managed, GemFire context.
*
* Defaults to {@literal false}.
*
* Use {@literal spring.data.gemfire.use-bean-factory-locator} property in {@literal application.properties}.
*/
boolean useBeanFactoryLocator() default false;

View File

@@ -28,6 +28,7 @@ import java.util.stream.Collectors;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.Pool;
import org.apache.geode.cache.server.CacheServer;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -37,10 +38,12 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.data.gemfire.GemfireUtils;
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
import org.springframework.data.gemfire.config.support.ClientRegionPoolBeanFactoryPostProcessor;
import org.springframework.data.gemfire.support.ConnectionEndpoint;
import org.springframework.data.gemfire.support.ConnectionEndpointList;
import org.springframework.util.StringUtils;
/**
* Spring {@link Configuration} class used to construct, configure and initialize
@@ -122,35 +125,36 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
ClientCacheFactoryBean gemfireCache = constructCacheFactoryBean();
gemfireCache.setClientCacheConfigurers(resolveClientCacheConfigurers());
gemfireCache.setDurableClientId(durableClientId());
gemfireCache.setDurableClientTimeout(durableClientTimeout());
gemfireCache.setFreeConnectionTimeout(freeConnectionTimeout());
gemfireCache.setIdleTimeout(idleTimeout());
gemfireCache.setKeepAlive(keepAlive());
gemfireCache.setLocators(poolLocators());
gemfireCache.setLoadConditioningInterval(loadConditioningInterval());
gemfireCache.setMaxConnections(maxConnections());
gemfireCache.setMinConnections(minConnections());
gemfireCache.setMultiUserAuthentication(multiUserAuthentication());
gemfireCache.setPingInterval(pingInterval());
gemfireCache.setPrSingleHopEnabled(prSingleHopEnabled());
gemfireCache.setReadTimeout(readTimeout());
gemfireCache.setReadyForEvents(readyForEvents());
gemfireCache.setRetryAttempts(retryAttempts());
gemfireCache.setServerGroup(serverGroup());
gemfireCache.setServers(poolServers());
gemfireCache.setSocketBufferSize(socketBufferSize());
gemfireCache.setStatisticsInterval(statisticsInterval());
gemfireCache.setSubscriptionAckInterval(subscriptionAckInterval());
gemfireCache.setSubscriptionEnabled(subscriptionEnabled());
gemfireCache.setSubscriptionMessageTrackingTimeout(subscriptionMessageTrackingTimeout());
gemfireCache.setSubscriptionRedundancy(subscriptionRedundancy());
gemfireCache.setThreadLocalConnections(threadLocalConnections());
gemfireCache.setDurableClientId(getDurableClientId());
gemfireCache.setDurableClientTimeout(getDurableClientTimeout());
gemfireCache.setFreeConnectionTimeout(getFreeConnectionTimeout());
gemfireCache.setIdleTimeout(getIdleTimeout());
gemfireCache.setKeepAlive(getKeepAlive());
gemfireCache.setLocators(getPoolLocators());
gemfireCache.setLoadConditioningInterval(getLoadConditioningInterval());
gemfireCache.setMaxConnections(getMaxConnections());
gemfireCache.setMinConnections(getMinConnections());
gemfireCache.setMultiUserAuthentication(getMultiUserAuthentication());
gemfireCache.setPingInterval(getPingInterval());
gemfireCache.setPrSingleHopEnabled(getPrSingleHopEnabled());
gemfireCache.setReadTimeout(getReadTimeout());
gemfireCache.setReadyForEvents(getReadyForEvents());
gemfireCache.setRetryAttempts(getRetryAttempts());
gemfireCache.setServerGroup(getServerGroup());
gemfireCache.setServers(getPoolServers());
gemfireCache.setSocketBufferSize(getSocketBufferSize());
gemfireCache.setStatisticsInterval(getStatisticsInterval());
gemfireCache.setSubscriptionAckInterval(getSubscriptionAckInterval());
gemfireCache.setSubscriptionEnabled(getSubscriptionEnabled());
gemfireCache.setSubscriptionMessageTrackingTimeout(getSubscriptionMessageTrackingTimeout());
gemfireCache.setSubscriptionRedundancy(getSubscriptionRedundancy());
gemfireCache.setThreadLocalConnections(getThreadLocalConnections());
return gemfireCache;
}
/* (non-Javadoc) */
@SuppressWarnings("all")
private List<ClientCacheConfigurer> resolveClientCacheConfigurers() {
return Optional.ofNullable(this.clientCacheConfigurers)
@@ -159,10 +163,12 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
Optional.of(this.beanFactory())
.filter(beanFactory -> beanFactory instanceof ListableBeanFactory)
.map(beanFactory -> {
Map<String, ClientCacheConfigurer> beansOfType = ((ListableBeanFactory) beanFactory)
.getBeansOfType(ClientCacheConfigurer.class, true, true);
return nullSafeMap(beansOfType).values().stream().collect(Collectors.toList());
})
.orElseGet(Collections::emptyList)
);
@@ -227,28 +233,109 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
Map<String, Object> clientCacheApplicationAttributes =
importMetadata.getAnnotationAttributes(getAnnotationTypeName());
setDurableClientId((String) clientCacheApplicationAttributes.get("durableClientId"));
setDurableClientTimeout((Integer) clientCacheApplicationAttributes.get("durableClientTimeout"));
setFreeConnectionTimeout((Integer) clientCacheApplicationAttributes.get("freeConnectionTimeout"));
setIdleTimeout((Long) clientCacheApplicationAttributes.get("idleTimeout"));
setKeepAlive(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("keepAlive")));
setLoadConditioningInterval((Integer) clientCacheApplicationAttributes.get("loadConditioningInterval"));
setMaxConnections((Integer) clientCacheApplicationAttributes.get("maxConnections"));
setMinConnections((Integer) clientCacheApplicationAttributes.get("minConnections"));
setMultiUserAuthentication(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("multiUserAuthentication")));
setPingInterval((Long) clientCacheApplicationAttributes.get("pingInterval"));
setPrSingleHopEnabled(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("prSingleHopEnabled")));
setReadTimeout((Integer) clientCacheApplicationAttributes.get("readTimeout"));
setReadyForEvents(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("readyForEvents")));
setRetryAttempts((Integer) clientCacheApplicationAttributes.get("retryAttempts"));
setServerGroup((String) clientCacheApplicationAttributes.get("serverGroup"));
setSocketBufferSize((Integer) clientCacheApplicationAttributes.get("socketBufferSize"));
setStatisticsInterval((Integer) clientCacheApplicationAttributes.get("statisticInterval"));
setSubscriptionAckInterval((Integer) clientCacheApplicationAttributes.get("subscriptionAckInterval"));
setSubscriptionEnabled(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("subscriptionEnabled")));
setSubscriptionMessageTrackingTimeout((Integer) clientCacheApplicationAttributes.get("subscriptionMessageTrackingTimeout"));
setSubscriptionRedundancy((Integer) clientCacheApplicationAttributes.get("subscriptionRedundancy"));
setThreadLocalConnections(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("threadLocalConnections")));
setDurableClientId(resolveProperty(cacheClientProperty("durable-client-id"),
(String) clientCacheApplicationAttributes.get("durableClientId")));
setDurableClientTimeout(resolveProperty(cacheClientProperty("durable-client-timeout"),
(Integer) clientCacheApplicationAttributes.get("durableClientTimeout")));
setFreeConnectionTimeout(
resolveProperty(namedPoolProperty("default", "free-connection-timeout"),
resolveProperty(poolProperty("free-connection-timeout"),
(Integer) clientCacheApplicationAttributes.get("freeConnectionTimeout"))));
setIdleTimeout(
resolveProperty(namedPoolProperty("default", "idle-timeout"),
resolveProperty(poolProperty("idle-timeout"),
(Long) clientCacheApplicationAttributes.get("idleTimeout"))));
setKeepAlive(resolveProperty(cacheClientProperty("keep-alive"),
Boolean.TRUE.equals(clientCacheApplicationAttributes.get("keepAlive"))));
setLoadConditioningInterval(
resolveProperty(namedPoolProperty("default","load-conditioning-interval"),
resolveProperty(poolProperty("load-conditioning-interval"),
(Integer) clientCacheApplicationAttributes.get("loadConditioningInterval"))));
setMaxConnections(
resolveProperty(namedPoolProperty("default", "max-connections"),
resolveProperty(poolProperty("max-connections"),
(Integer) clientCacheApplicationAttributes.get("maxConnections"))));
setMinConnections(
resolveProperty(namedPoolProperty("default", "min-connections"),
resolveProperty(poolProperty("min-connections"),
(Integer) clientCacheApplicationAttributes.get("minConnections"))));
setMultiUserAuthentication(
resolveProperty(namedPoolProperty("default", "multi-user-authentication"),
resolveProperty(poolProperty("multi-user-authentication"),
Boolean.TRUE.equals(clientCacheApplicationAttributes.get("multiUserAuthentication")))));
setPingInterval(
resolveProperty(namedPoolProperty("default", "ping-interval"),
resolveProperty(poolProperty("ping-interval"),
(Long) clientCacheApplicationAttributes.get("pingInterval"))));
setPrSingleHopEnabled(
resolveProperty(namedPoolProperty("default", "pr-single-hop-enabled"),
resolveProperty(poolProperty("pr-single-hop-enabled"),
Boolean.TRUE.equals(clientCacheApplicationAttributes.get("prSingleHopEnabled")))));
setReadTimeout(
resolveProperty(namedPoolProperty("default", "read-timeout"),
resolveProperty(poolProperty("read-timeout"),
(Integer) clientCacheApplicationAttributes.get("readTimeout"))));
setReadyForEvents(
resolveProperty(namedPoolProperty("default", "ready-for-events"),
resolveProperty(poolProperty("ready-for-events"),
Boolean.TRUE.equals(clientCacheApplicationAttributes.get("readyForEvents")))));
setRetryAttempts(
resolveProperty(namedPoolProperty("default", "retry-attempts"),
resolveProperty(poolProperty("retry-attempts"),
(Integer) clientCacheApplicationAttributes.get("retryAttempts"))));
setServerGroup(
resolveProperty(namedPoolProperty("default", "server-group"),
resolveProperty(poolProperty("server-group"),
(String) clientCacheApplicationAttributes.get("serverGroup"))));
setSocketBufferSize(
resolveProperty(namedPoolProperty("default", "socket-buffer-size"),
resolveProperty(poolProperty("socket-buffer-size"),
(Integer) clientCacheApplicationAttributes.get("socketBufferSize"))));
setStatisticsInterval(
resolveProperty(namedPoolProperty("default", "statistic-interval"),
resolveProperty(poolProperty("statistic-interval"),
(Integer) clientCacheApplicationAttributes.get("statisticInterval"))));
setSubscriptionAckInterval(
resolveProperty(namedPoolProperty("default", "subscription-ack-interval"),
resolveProperty(poolProperty("subscription-ack-interval"),
(Integer) clientCacheApplicationAttributes.get("subscriptionAckInterval"))));
setSubscriptionEnabled(
resolveProperty(namedPoolProperty("default", "subscription-enabled"),
resolveProperty(poolProperty("subscription-enabled"),
Boolean.TRUE.equals(clientCacheApplicationAttributes.get("subscriptionEnabled")))));
setSubscriptionMessageTrackingTimeout(
resolveProperty(namedPoolProperty("default", "subscription-message-tracking-timeout"),
resolveProperty(poolProperty("subscription-message-tracking-timeout"),
(Integer) clientCacheApplicationAttributes.get("subscriptionMessageTrackingTimeout"))));
setSubscriptionRedundancy(
resolveProperty(namedPoolProperty("default", "subscription-redundancy"),
resolveProperty(poolProperty("subscription-redundancy"),
(Integer) clientCacheApplicationAttributes.get("subscriptionRedundancy"))));
setThreadLocalConnections(
resolveProperty(namedPoolProperty("default", "thread-local-connections"),
resolveProperty(poolProperty("thread-local-connections"),
Boolean.TRUE.equals(clientCacheApplicationAttributes.get("threadLocalConnections")))));
configureLocatorsAndServers(clientCacheApplicationAttributes);
}
@@ -265,22 +352,44 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
*/
private void configureLocatorsAndServers(Map<String, Object> clientCacheApplicationAttributes) {
ConnectionEndpointList poolLocators = new ConnectionEndpointList();
ConnectionEndpointList poolLocators;
AnnotationAttributes[] locators = (AnnotationAttributes[]) clientCacheApplicationAttributes.get("locators");
String locatorsFromProperty = resolveProperty(namedPoolProperty("default", "locators"),
resolveProperty(poolProperty("locators"), (String) null));
for (AnnotationAttributes locator : locators) {
poolLocators.add(newConnectionEndpoint((String) locator.get("host"), (Integer) locator.get("port")));
if (StringUtils.hasText(locatorsFromProperty)) {
String[] locatorHostsPorts = locatorsFromProperty.split(",");
poolLocators = ConnectionEndpointList.parse(GemfireUtils.DEFAULT_LOCATOR_PORT, locatorHostsPorts);
}
else {
poolLocators = new ConnectionEndpointList();
AnnotationAttributes[] locators = (AnnotationAttributes[]) clientCacheApplicationAttributes.get("locators");
for (AnnotationAttributes locator : locators) {
poolLocators.add(newConnectionEndpoint((String) locator.get("host"), (Integer) locator.get("port")));
}
}
setPoolLocators(poolLocators);
ConnectionEndpointList poolServers = new ConnectionEndpointList();
ConnectionEndpointList poolServers;
AnnotationAttributes[] servers = (AnnotationAttributes[]) clientCacheApplicationAttributes.get("servers");
String serversFromProperty = resolveProperty(namedPoolProperty("default", "servers"),
resolveProperty(poolProperty("servers"), (String) null));
for (AnnotationAttributes server : servers) {
poolServers.add(newConnectionEndpoint((String) server.get("host"), (Integer) server.get("port")));
if (StringUtils.hasText(serversFromProperty)) {
String[] serverHostsPorts = serversFromProperty.split(",");
poolServers = ConnectionEndpointList.parse(CacheServer.DEFAULT_PORT, serverHostsPorts);
}
else {
poolServers = new ConnectionEndpointList();
AnnotationAttributes[] servers = (AnnotationAttributes[]) clientCacheApplicationAttributes.get("servers");
for (AnnotationAttributes server : servers) {
poolServers.add(newConnectionEndpoint((String) server.get("host"), (Integer) server.get("port")));
}
}
setPoolServers(poolServers);
@@ -304,7 +413,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.durableClientId = durableClientId;
}
protected String durableClientId() {
protected String getDurableClientId() {
return this.durableClientId;
}
@@ -313,7 +422,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.durableClientTimeout = durableClientTimeout;
}
protected Integer durableClientTimeout() {
protected Integer getDurableClientTimeout() {
return this.durableClientTimeout;
}
@@ -322,7 +431,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.freeConnectionTimeout = freeConnectionTimeout;
}
protected Integer freeConnectionTimeout() {
protected Integer getFreeConnectionTimeout() {
return this.freeConnectionTimeout;
}
@@ -331,7 +440,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.idleTimeout = idleTimeout;
}
protected Long idleTimeout() {
protected Long getIdleTimeout() {
return this.idleTimeout;
}
@@ -340,7 +449,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.keepAlive = keepAlive;
}
protected Boolean keepAlive() {
protected Boolean getKeepAlive() {
return this.keepAlive;
}
@@ -349,7 +458,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.loadConditioningInterval = loadConditioningInterval;
}
protected Integer loadConditioningInterval() {
protected Integer getLoadConditioningInterval() {
return this.loadConditioningInterval;
}
@@ -358,7 +467,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.maxConnections = maxConnections;
}
protected Integer maxConnections() {
protected Integer getMaxConnections() {
return this.maxConnections;
}
@@ -367,7 +476,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.minConnections = minConnections;
}
protected Integer minConnections() {
protected Integer getMinConnections() {
return this.minConnections;
}
@@ -376,7 +485,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.multiUserAuthentication = multiUserAuthentication;
}
protected Boolean multiUserAuthentication() {
protected Boolean getMultiUserAuthentication() {
return this.multiUserAuthentication;
}
@@ -385,7 +494,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.pingInterval = pingInterval;
}
protected Long pingInterval() {
protected Long getPingInterval() {
return this.pingInterval;
}
@@ -394,7 +503,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.locators = locators;
}
protected Iterable<ConnectionEndpoint> poolLocators() {
protected Iterable<ConnectionEndpoint> getPoolLocators() {
return this.locators;
}
@@ -403,7 +512,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.servers = servers;
}
protected Iterable<ConnectionEndpoint> poolServers() {
protected Iterable<ConnectionEndpoint> getPoolServers() {
return this.servers;
}
@@ -412,7 +521,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.prSingleHopEnabled = prSingleHopEnabled;
}
protected Boolean prSingleHopEnabled() {
protected Boolean getPrSingleHopEnabled() {
return this.prSingleHopEnabled;
}
@@ -421,7 +530,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.readTimeout = readTimeout;
}
protected Integer readTimeout() {
protected Integer getReadTimeout() {
return this.readTimeout;
}
@@ -430,7 +539,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.readyForEvents = readyForEvents;
}
protected boolean readyForEvents() {
protected boolean getReadyForEvents() {
return this.readyForEvents;
}
@@ -439,7 +548,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.retryAttempts = retryAttempts;
}
protected Integer retryAttempts() {
protected Integer getRetryAttempts() {
return this.retryAttempts;
}
@@ -448,7 +557,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.serverGroup = serverGroup;
}
protected String serverGroup() {
protected String getServerGroup() {
return this.serverGroup;
}
@@ -457,7 +566,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.socketBufferSize = socketBufferSize;
}
protected Integer socketBufferSize() {
protected Integer getSocketBufferSize() {
return this.socketBufferSize;
}
@@ -466,7 +575,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.statisticsInterval = statisticsInterval;
}
protected Integer statisticsInterval() {
protected Integer getStatisticsInterval() {
return this.statisticsInterval;
}
@@ -475,7 +584,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.subscriptionAckInterval = subscriptionAckInterval;
}
protected Integer subscriptionAckInterval() {
protected Integer getSubscriptionAckInterval() {
return this.subscriptionAckInterval;
}
@@ -484,7 +593,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.subscriptionEnabled = subscriptionEnabled;
}
protected Boolean subscriptionEnabled() {
protected Boolean getSubscriptionEnabled() {
return this.subscriptionEnabled;
}
@@ -493,7 +602,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.subscriptionMessageTrackingTimeout = subscriptionMessageTrackingTimeout;
}
protected Integer subscriptionMessageTrackingTimeout() {
protected Integer getSubscriptionMessageTrackingTimeout() {
return this.subscriptionMessageTrackingTimeout;
}
@@ -502,7 +611,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.subscriptionRedundancy = subscriptionRedundancy;
}
protected Integer subscriptionRedundancy() {
protected Integer getSubscriptionRedundancy() {
return this.subscriptionRedundancy;
}
@@ -511,7 +620,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration {
this.threadLocalConnections = threadLocalConnections;
}
protected Boolean threadLocalConnections() {
protected Boolean getThreadLocalConnections() {
return this.threadLocalConnections;
}

View File

@@ -17,17 +17,20 @@
package org.springframework.data.gemfire.config.annotation;
import static java.util.Arrays.stream;
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeMap;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.apache.geode.cache.DiskStore;
import org.apache.geode.cache.DiskStoreFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -38,14 +41,16 @@ import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.DiskStoreFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport;
import org.springframework.data.gemfire.config.xml.GemfireConstants;
import org.springframework.data.gemfire.util.ArrayUtils;
import org.springframework.util.StringUtils;
/**
* The {@link DiskStoreConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} used to register
* a GemFire/Geode {@link org.apache.geode.cache.DiskStore} bean definition.
*
* @author John Blum
* @see org.apache.geode.cache.DiskStore
* @see org.springframework.beans.factory.config.BeanDefinition
* @see org.springframework.beans.factory.support.BeanDefinitionBuilder
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
@@ -54,34 +59,61 @@ import org.springframework.data.gemfire.util.ArrayUtils;
* @see org.springframework.data.gemfire.config.annotation.EnableDiskStore
* @see org.springframework.data.gemfire.config.annotation.EnableDiskStores
* @see org.springframework.data.gemfire.config.annotation.DiskStoreConfigurer
* @see org.apache.geode.cache.DiskStore
* @see org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport
* @since 1.9.0
*/
public class DiskStoreConfiguration implements BeanFactoryAware, ImportBeanDefinitionRegistrar {
public class DiskStoreConfiguration extends AbstractAnnotationConfigSupport
implements ImportBeanDefinitionRegistrar {
private BeanFactory beanFactory;
protected static final boolean DEFAULT_ALLOW_FORCE_COMPACTION = DiskStoreFactory.DEFAULT_ALLOW_FORCE_COMPACTION;
protected static final boolean DEFAULT_AUTO_COMPACT = DiskStoreFactory.DEFAULT_AUTO_COMPACT;
protected static final float DEFAULT_DISK_USAGE_CRITICAL_PERCENTAGE =
DiskStoreFactory.DEFAULT_DISK_USAGE_CRITICAL_PERCENTAGE;
protected static final float DEFAULT_DISK_USAGE_WARNING_PERCENTAGE =
DiskStoreFactory.DEFAULT_DISK_USAGE_WARNING_PERCENTAGE;
protected static final int DEFAULT_COMPACTION_THRESHOLD = DiskStoreFactory.DEFAULT_COMPACTION_THRESHOLD;
protected static final int DEFAULT_QUEUE_SIZE = DiskStoreFactory.DEFAULT_QUEUE_SIZE;
protected static final int DEFAULT_WRITE_BUFFER_SIZE = DiskStoreFactory.DEFAULT_WRITE_BUFFER_SIZE;
protected static final long DEFAULT_MAX_OPLOG_SIZE = 1024L;
protected static final long DEFAULT_TIME_INTERVAL = DiskStoreFactory.DEFAULT_TIME_INTERVAL;
@Autowired(required = false)
private List<DiskStoreConfigurer> diskStoreConfigurers = Collections.emptyList();
/**
* Returns the {@link DiskStore} {@link java.lang.annotation.Annotation} type specified in configuration.
*
* @return the {@link DiskStore} {@link java.lang.annotation.Annotation} type specified in configuration.
* @see org.springframework.data.gemfire.config.annotation.EnableDiskStores
* @see org.springframework.data.gemfire.config.annotation.EnableDiskStore
*/
@Override
protected Class getAnnotationType() {
return EnableDiskStore.class;
}
/**
* @inheritDoc
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (importingClassMetadata.hasAnnotation(EnableDiskStore.class.getName())) {
if (importingClassMetadata.hasAnnotation(getAnnotationTypeName())) {
AnnotationAttributes enableDiskStoreAttributes = AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableDiskStore.class.getName()));
AnnotationAttributes enableDiskStoreAttributes =
AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(getAnnotationTypeName()));
registerDiskStoreBeanDefinition(importingClassMetadata, enableDiskStoreAttributes, registry);
registerDiskStoreBeanDefinition(enableDiskStoreAttributes, registry);
}
}
/* (non-Javadoc) */
protected void registerDiskStoreBeanDefinition(AnnotationMetadata importingClassMetadata,
AnnotationAttributes enableDiskStoreAttributes, BeanDefinitionRegistry registry) {
protected void registerDiskStoreBeanDefinition(AnnotationAttributes enableDiskStoreAttributes,
BeanDefinitionRegistry registry) {
BeanDefinitionBuilder diskStoreFactoryBeanBuilder =
BeanDefinitionBuilder.genericBeanDefinition(DiskStoreFactoryBean.class);
@@ -95,33 +127,80 @@ public class DiskStoreConfiguration implements BeanFactoryAware, ImportBeanDefin
diskStoreFactoryBeanBuilder.addPropertyValue("diskStoreConfigurers", resolveDiskStoreConfigurers());
setPropertyValueIfNotDefault(diskStoreFactoryBeanBuilder, "allowForceCompaction",
enableDiskStoreAttributes.getBoolean("allowForceCompaction"), false);
enableDiskStoreAttributes.getBoolean("allowForceCompaction"), DEFAULT_ALLOW_FORCE_COMPACTION);
Optional.ofNullable(resolveProperty(namedDiskStoreProperty(diskStoreName, "allow-force-compaction"),
resolveProperty(diskStoreProperty("allow-force-compaction"), (Boolean) null)))
.ifPresent(allowForceCompaction ->
diskStoreFactoryBeanBuilder.addPropertyValue("allowForceCompaction", allowForceCompaction));
setPropertyValueIfNotDefault(diskStoreFactoryBeanBuilder, "autoCompact",
enableDiskStoreAttributes.getBoolean("autoCompact"), false);
enableDiskStoreAttributes.getBoolean("autoCompact"), DEFAULT_AUTO_COMPACT);
Optional.ofNullable(resolveProperty(namedDiskStoreProperty(diskStoreName, "auto-compact"),
resolveProperty(diskStoreProperty("auto-compact"), (Boolean) null)))
.ifPresent(autoCompact -> diskStoreFactoryBeanBuilder.addPropertyValue("autoCompact", autoCompact));
setPropertyValueIfNotDefault(diskStoreFactoryBeanBuilder, "compactionThreshold",
enableDiskStoreAttributes.<Integer>getNumber("compactionThreshold"), 50);
enableDiskStoreAttributes.<Integer>getNumber("compactionThreshold"),
DEFAULT_COMPACTION_THRESHOLD);
Optional.ofNullable(resolveProperty(namedDiskStoreProperty(diskStoreName, "compaction-threshold"),
resolveProperty(diskStoreProperty("compaction-threshold"), (Integer) null)))
.ifPresent(compactionThreshold ->
diskStoreFactoryBeanBuilder.addPropertyValue("compactionThreshold", compactionThreshold));
setPropertyValueIfNotDefault(diskStoreFactoryBeanBuilder, "diskUsageCriticalPercentage",
enableDiskStoreAttributes.<Float>getNumber("diskUsageCriticalPercentage"), 99.0f);
enableDiskStoreAttributes.<Float>getNumber("diskUsageCriticalPercentage"),
DEFAULT_DISK_USAGE_CRITICAL_PERCENTAGE);
Optional.ofNullable(resolveProperty(namedDiskStoreProperty(diskStoreName, "disk-usage-critical-percentage"),
resolveProperty(diskStoreProperty("disk-usage-critical-percentage"), (Float) null)))
.ifPresent(diskUsageCriticalPercentage ->
diskStoreFactoryBeanBuilder.addPropertyValue("diskUsageCriticalPercentage", diskUsageCriticalPercentage));
setPropertyValueIfNotDefault(diskStoreFactoryBeanBuilder, "diskUsageWarningPercentage",
enableDiskStoreAttributes.<Float>getNumber("diskUsageWarningPercentage"), 90.0f);
enableDiskStoreAttributes.<Float>getNumber("diskUsageWarningPercentage"),
DEFAULT_DISK_USAGE_WARNING_PERCENTAGE);
Optional.ofNullable(resolveProperty(namedDiskStoreProperty(diskStoreName, "disk-usage-warning-percentage"),
resolveProperty(diskStoreProperty("disk-usage-warning-percentage"), (Float) null)))
.ifPresent(diskUsageWarningPercentage ->
diskStoreFactoryBeanBuilder.addPropertyValue("diskUsageWarningPercentage", diskUsageWarningPercentage));
setPropertyValueIfNotDefault(diskStoreFactoryBeanBuilder, "maxOplogSize",
enableDiskStoreAttributes.<Long>getNumber("maxOplogSize"), 1024L);
enableDiskStoreAttributes.<Long>getNumber("maxOplogSize"), DEFAULT_MAX_OPLOG_SIZE);
Optional.ofNullable(resolveProperty(namedDiskStoreProperty(diskStoreName, "max-oplog-size"),
resolveProperty(diskStoreProperty("max-oplog-size"), (Long) null)))
.ifPresent(maxOplogSize ->
diskStoreFactoryBeanBuilder.addPropertyValue("maxOplogSize", maxOplogSize));
setPropertyValueIfNotDefault(diskStoreFactoryBeanBuilder, "queueSize",
enableDiskStoreAttributes.<Integer>getNumber("queueSize"), 0);
enableDiskStoreAttributes.<Integer>getNumber("queueSize"), DEFAULT_QUEUE_SIZE);
Optional.ofNullable(resolveProperty(namedDiskStoreProperty(diskStoreName, "queue-size"),
resolveProperty(diskStoreProperty("queue-size"), (Integer) null)))
.ifPresent(queueSize ->
diskStoreFactoryBeanBuilder.addPropertyValue("queueSize", queueSize));
setPropertyValueIfNotDefault(diskStoreFactoryBeanBuilder, "timeInterval",
enableDiskStoreAttributes.<Long>getNumber("timeInterval"), 1000L);
enableDiskStoreAttributes.<Long>getNumber("timeInterval"), DEFAULT_TIME_INTERVAL);
Optional.ofNullable(resolveProperty(namedDiskStoreProperty(diskStoreName, "time-interval"),
resolveProperty(diskStoreProperty("time-interval"), (Long) null)))
.ifPresent(timeInterval ->
diskStoreFactoryBeanBuilder.addPropertyValue("timeInterval", timeInterval));
setPropertyValueIfNotDefault(diskStoreFactoryBeanBuilder, "writeBufferSize",
enableDiskStoreAttributes.<Integer>getNumber("writeBufferSize"), 32768);
enableDiskStoreAttributes.<Integer>getNumber("writeBufferSize"), DEFAULT_WRITE_BUFFER_SIZE);
parseDiskStoreDiskDirectories(importingClassMetadata, enableDiskStoreAttributes, diskStoreFactoryBeanBuilder);
Optional.ofNullable(resolveProperty(namedDiskStoreProperty(diskStoreName, "write-buffer-size"),
resolveProperty(diskStoreProperty("write-buffer-size"), (Integer) null)))
.ifPresent(writeBufferSize ->
diskStoreFactoryBeanBuilder.addPropertyValue("writeBufferSize", writeBufferSize));
resolveDiskStoreDirectories(diskStoreName, enableDiskStoreAttributes, diskStoreFactoryBeanBuilder);
registry.registerBeanDefinition(diskStoreName, diskStoreFactoryBeanBuilder.getBeanDefinition());
}
@@ -132,42 +211,143 @@ public class DiskStoreConfiguration implements BeanFactoryAware, ImportBeanDefin
return Optional.ofNullable(this.diskStoreConfigurers)
.filter(diskStoreConfigurers -> !diskStoreConfigurers.isEmpty())
.orElseGet(() ->
Optional.of(this.beanFactory)
Optional.of(this.beanFactory())
.filter(beanFactory -> beanFactory instanceof ListableBeanFactory)
.map(beanFactory -> {
Map<String, DiskStoreConfigurer> beansOfType = ((ListableBeanFactory) beanFactory)
.getBeansOfType(DiskStoreConfigurer.class, true, true);
return nullSafeMap(beansOfType).values().stream().collect(Collectors.toList());
})
.orElseGet(Collections::emptyList)
);
}
/* (non-Javadoc) */
protected BeanDefinitionBuilder parseDiskStoreDiskDirectories(AnnotationMetadata importingClassMetadata,
AnnotationAttributes enableDiskStoreAttributes, BeanDefinitionBuilder diskStoreBeanFactoryBuilder) {
protected BeanDefinitionBuilder resolveDiskStoreDirectories(String diskStoreName,
AnnotationAttributes enableDiskStoreAttributes, BeanDefinitionBuilder diskStoreFactoryBeanBuilder) {
AnnotationAttributes[] diskDirectories = ArrayUtils.nullSafeArray(
enableDiskStoreAttributes.getAnnotationArray("diskDirectories"), AnnotationAttributes.class);
ManagedList<BeanDefinition> diskStoreDirectoryBeans = new ManagedList<>();
ManagedList<BeanDefinition> diskDirectoryBeans = new ManagedList<BeanDefinition>(diskDirectories.length);
String diskStoreDirectoryLocation =
resolveProperty(diskStoreProperty("directory.location"), String.class);
for (AnnotationAttributes diskDirectoryAttributes : diskDirectories) {
BeanDefinitionBuilder diskDirectoryBuilder =
BeanDefinitionBuilder.genericBeanDefinition(DiskStoreFactoryBean.DiskDir.class);
String namedDiskStoreDirectoryLocation =
resolveProperty(namedDiskStoreProperty(diskStoreName, "directory.location"), String.class);
diskDirectoryBuilder.addConstructorArgValue(diskDirectoryAttributes.getString("location"));
diskDirectoryBuilder.addConstructorArgValue(diskDirectoryAttributes.<Integer>getNumber("maxSize"));
Integer diskStoreDirectorySize =
resolveProperty(diskStoreProperty("directory.size"), Integer.class);
diskDirectoryBeans.add(diskDirectoryBuilder.getBeanDefinition());
Integer namedDiskStoreDirectorySize =
resolveProperty(namedDiskStoreProperty(diskStoreName, "directory.size"), Integer.class);
List<String> namedDiskStoreDirectoryLocationProperties = arrayOfPropertyNamesFor(
namedDiskStoreProperty(diskStoreName, "directory"), "location");
if (!namedDiskStoreDirectoryLocationProperties.isEmpty()) {
AtomicInteger index = new AtomicInteger(0);
namedDiskStoreDirectoryLocationProperties.forEach(property -> {
String location = requireProperty(property, String.class);
Integer maxSize = resolveProperty(asArrayProperty(
namedDiskStoreProperty(diskStoreName, "directory"), index.getAndIncrement(),
"size"), Integer.class);
maxSize = resolveDiskStoreDirectorySize(maxSize, namedDiskStoreDirectorySize, diskStoreDirectorySize);
diskStoreDirectoryBeans.add(newDiskStoreDirectoryBean(location, maxSize));
});
}
else if (Optional.ofNullable(namedDiskStoreDirectoryLocation).filter(StringUtils::hasText).isPresent()) {
diskStoreDirectoryBeans.add(newDiskStoreDirectoryBean(namedDiskStoreDirectoryLocation,
resolveDiskStoreDirectorySize(namedDiskStoreDirectorySize, diskStoreDirectorySize)));
}
else {
List<String> diskStoreDirectoryLocationProperties =
arrayOfPropertyNamesFor(diskStoreProperty("directory"), "location");
if (!diskStoreDirectoryLocationProperties.isEmpty()) {
AtomicInteger index = new AtomicInteger(0);
diskStoreDirectoryLocationProperties.forEach(property -> {
String location = requireProperty(property, String.class);
Integer maxSize = resolveProperty(asArrayProperty(diskStoreProperty("directory"),
index.getAndIncrement(), "size"), Integer.class);
maxSize = resolveDiskStoreDirectorySize(namedDiskStoreDirectorySize, maxSize,
diskStoreDirectorySize);
diskStoreDirectoryBeans.add(newDiskStoreDirectoryBean(location, maxSize));
});
}
else if (Optional.ofNullable(diskStoreDirectoryLocation).filter(StringUtils::hasText).isPresent()) {
diskStoreDirectoryBeans.add(newDiskStoreDirectoryBean(diskStoreDirectoryLocation,
resolveDiskStoreDirectorySize(namedDiskStoreDirectorySize, diskStoreDirectorySize)));
}
else {
diskStoreDirectoryBeans.addAll(parseDiskStoreDirectories(enableDiskStoreAttributes));
}
}
if (!diskDirectoryBeans.isEmpty()) {
diskStoreBeanFactoryBuilder.addPropertyValue("diskDirs", diskDirectoryBeans);
}
Optional.of(diskStoreDirectoryBeans)
.filter(beans -> !beans.isEmpty())
.ifPresent(beans -> diskStoreFactoryBeanBuilder.addPropertyValue("diskDirs", diskStoreDirectoryBeans));
return diskStoreBeanFactoryBuilder;
return diskStoreFactoryBeanBuilder;
}
/* (non-Javadoc) */
@SuppressWarnings("unused")
private String resolveDiskStoreDirectoryLocation(String... locations) {
return stream(nullSafeArray(locations, String.class))
.filter(StringUtils::hasText)
.findFirst()
.orElse(".");
}
/* (non-Javadoc) */
private Integer resolveDiskStoreDirectorySize(Integer... sizes) {
return stream(nullSafeArray(sizes, Integer.class))
.filter(Objects::nonNull)
.findFirst()
.orElse(Integer.MAX_VALUE);
}
/* (non-Javadoc) */
protected ManagedList<BeanDefinition> parseDiskStoreDirectories(AnnotationAttributes enableDiskStoreAttributes) {
AnnotationAttributes[] diskDirectories =
enableDiskStoreAttributes.getAnnotationArray("diskDirectories");
ManagedList<BeanDefinition> diskDirectoryBeans = new ManagedList<>(diskDirectories.length);
stream(nullSafeArray(diskDirectories, AnnotationAttributes.class)).forEach(diskDirectoryAttributes ->
diskDirectoryBeans.add(newDiskStoreDirectoryBean(diskDirectoryAttributes.getString("location"),
diskDirectoryAttributes.getNumber("maxSize"))));
return diskDirectoryBeans;
}
/* (non-Javadoc) */
private BeanDefinition newDiskStoreDirectoryBean(String location, Integer maxSize) {
BeanDefinitionBuilder diskDirectoryBuilder =
BeanDefinitionBuilder.genericBeanDefinition(DiskStoreFactoryBean.DiskDir.class);
diskDirectoryBuilder.addConstructorArgValue(location);
diskDirectoryBuilder.addConstructorArgValue(maxSize);
return diskDirectoryBuilder.getBeanDefinition();
}
/* (non-Javadoc) */
@@ -177,9 +357,4 @@ public class DiskStoreConfiguration implements BeanFactoryAware, ImportBeanDefin
return (value != null && !value.equals(defaultValue) ?
beanDefinitionBuilder.addPropertyValue(propertyName, value) : beanDefinitionBuilder);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}

View File

@@ -17,10 +17,12 @@
package org.springframework.data.gemfire.config.annotation;
import static java.util.Arrays.stream;
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.util.ArrayUtils;
/**
* The {@link DiskStoresConfiguration} class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
@@ -36,22 +38,21 @@ import org.springframework.data.gemfire.util.ArrayUtils;
*/
public class DiskStoresConfiguration extends DiskStoreConfiguration {
/**
* @inheritDoc
*/
/* (non-Javadoc) */
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (importingClassMetadata.hasAnnotation(EnableDiskStores.class.getName())) {
AnnotationAttributes enableDiskStoresAttributes = AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableDiskStores.class.getName()));
AnnotationAttributes[] diskStores = ArrayUtils.nullSafeArray(
enableDiskStoresAttributes.getAnnotationArray("diskStores"), AnnotationAttributes.class);
AnnotationAttributes[] diskStores =
enableDiskStoresAttributes.getAnnotationArray("diskStores");
for (AnnotationAttributes diskStoreAttributes : diskStores) {
registerDiskStoreBeanDefinition(importingClassMetadata,
mergeDiskStoreAttributes(enableDiskStoresAttributes, diskStoreAttributes), registry);
}
stream(nullSafeArray(diskStores, AnnotationAttributes.class)).forEach(diskStoreAttributes ->
registerDiskStoreBeanDefinition(
mergeDiskStoreAttributes(enableDiskStoresAttributes, diskStoreAttributes), registry));
}
}

View File

@@ -27,13 +27,15 @@ import java.lang.annotation.Target;
import org.apache.geode.security.AccessControl;
import org.apache.geode.security.AuthInitialize;
import org.apache.geode.security.Authenticator;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The EnableAuth annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
* annotated class to configure and enable GemFire/Geode's Authentication and Authorization framework services.
* The {@link EnableAuth} annotation marks a Spring {@link Configuration @Configuration} annotated {@link Class}
* to configure and enable Pivotal GemFire/Apache Geode's Authentication and Authorization framework and services.
*
* @author John Blum
* @see java.lang.annotation.Annotation
* @see org.apache.geode.security.AccessControl
* @see org.apache.geode.security.AuthInitialize
* @see org.apache.geode.security.Authenticator
@@ -57,6 +59,8 @@ public @interface EnableAuth {
* in the pre-operation phase, which is when the request for the operation is received from the client.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.security.client.accessor} property in {@literal application.properties}.
*/
String clientAccessor() default "";
@@ -67,8 +71,11 @@ public @interface EnableAuth {
* through the notification channel.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.security.client.accessor-post-processor} property
* in {@literal application.properties}.
*/
String clientAccessPostOperation() default "";
String clientAccessorPostProcessor() default "";
/**
* Used for authentication. Static creation method returning an {@link AuthInitialize} object,
@@ -77,6 +84,9 @@ public @interface EnableAuth {
* on the clients.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.security.client.authentication-initializer} property
* in {@literal application.properties}.
*/
String clientAuthenticationInitializer() default "";
@@ -85,6 +95,9 @@ public @interface EnableAuth {
* which is used by a server to verify the credentials of the connecting client.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.security.client.authenticator} property
* in {@literal application.properties}.
*/
String clientAuthenticator() default "";
@@ -95,6 +108,9 @@ public @interface EnableAuth {
* supported by the JDK.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.security.client.diffie-hellman-algorithm} property
* in {@literal application.properties}.
*/
String clientDiffieHellmanAlgorithm() default "";
@@ -104,6 +120,9 @@ public @interface EnableAuth {
* {@link Authenticator} specified through the {@literal security-peer-authenticator} property on the peers.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.security.peer.authentication-initializer} property
* in {@literal application.properties}.
*/
String peerAuthenticationInitializer() default "";
@@ -112,6 +131,8 @@ public @interface EnableAuth {
* by a peer to verify the credentials of the connecting peer.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.security.peer.authenticator} property in {@literal application.properties}.
*/
String peerAuthenticator() default "";
@@ -120,6 +141,9 @@ public @interface EnableAuth {
* authenticated peer requesting a secure connection.
*
* Defaults to {@literal 1000} milliseconds.
*
* Use the {@literal spring.data.gemfire.security.peer.verify-member-timeout} property
* in {@literal application.properties}.
*/
long peerVerifyMemberTimeout() default AuthConfiguration.DEFAULT_PEER_VERIFY_MEMBER_TIMEOUT;
@@ -128,6 +152,8 @@ public @interface EnableAuth {
* regular log file is used.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.security.log.file} property in {@literal application.properties}.
*/
String securityLogFile() default "";
@@ -138,6 +164,8 @@ public @interface EnableAuth {
* {@literal error}, {@literal severe}, and {@literal none}.
*
* Defaults to {@literal config}.
*
* Use the {@literal spring.data.gemfire.security.log.level} property in {@literal application.properties}.
*/
String securityLogLevel() default AuthConfiguration.DEFAULT_SECURITY_LOG_LEVEL;
@@ -152,6 +180,8 @@ public @interface EnableAuth {
* or write access for your {@literal gemfire.properties} file.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.security.properties-file} property in {@literal application.properties}.
*/
String securityPropertiesFile() default "";

View File

@@ -36,6 +36,7 @@ import org.springframework.context.annotation.Import;
* expression or a Spring property placeholder.
*
* @author John Blum
* @see org.springframework.data.gemfire.RegionFactoryBean#setLookupEnabled(Boolean)
* @see org.springframework.data.gemfire.config.annotation.AutoRegionLookupConfiguration
* @since 1.9.0
*/
@@ -48,13 +49,13 @@ import org.springframework.context.annotation.Import;
public @interface EnableAutoRegionLookup {
/**
* Attribute to indicate whether auto {@link org.apache.geode.cache.Region} lookup should be enabled;
* Attribute indicating whether auto {@link org.apache.geode.cache.Region} lookup should be enabled;
*
* Defaults to {@literal true}.
*
* This attribute accepts either a SpEL or Spring property placeholder expression so that
* auto {@link org.apache.geode.cache.Region} lookup behavior can be determined
* at application configuration time.
* Use the {@literal spring.data.gemfire.enable-auto-region-lookup} in {@literal application.properties}
* to dynamically customize this configuration setting.
*/
String enabled() default "true";
boolean enabled() default true;
}

View File

@@ -58,14 +58,22 @@ public @interface EnableCacheServer {
/**
* Configures whether the {@link CacheServer} should start automatically at runtime.
*
* Default is {@literal true).
* Defaults to {@literal true).
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.auto-startup} property
* or the {@literal spring.data.gemfire.cache.server.auto-startup} property
* in {@literal application.properties}.
*/
boolean autoStartup() default true;
/**
* Configures the ip address or host name that this cache server will listen on.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_BIND_ADDRESS
* Defaults to {@link CacheServer#DEFAULT_BIND_ADDRESS}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.bind-address} property
* or the {@literal spring.data.gemfire.cache.server.bind-address} property
* in {@literal application.properties}.
*/
String bindAddress() default CacheServer.DEFAULT_BIND_ADDRESS;
@@ -73,82 +81,131 @@ public @interface EnableCacheServer {
* Configures the ip address or host name that server locators will tell clients that this cache server
* is listening on.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_HOSTNAME_FOR_CLIENTS
* Defaults to {@link CacheServer#DEFAULT_HOSTNAME_FOR_CLIENTS}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.hostname-for-clients} property
* or the {@literal spring.data.gemfire.cache.server.hostname-for-clients} property
* in {@literal application.properties}.
*/
String hostnameForClients() default CacheServer.DEFAULT_HOSTNAME_FOR_CLIENTS;
/**
* Configures the frequency in milliseconds to poll the load probe on this cache server.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_LOAD_POLL_INTERVAL
* Defaults to {@link CacheServer#DEFAULT_LOAD_POLL_INTERVAL}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.load-poll-interval} property
* or the {@literal spring.data.gemfire.cache.server.load-poll-interval} property
* in {@literal application.properties}.
*/
long loadPollInterval() default CacheServer.DEFAULT_LOAD_POLL_INTERVAL;
/**
* Configures the maximum allowed client connections.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_MAX_CONNECTIONS
* Defaults to {@link CacheServer#DEFAULT_MAX_CONNECTIONS}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.max-connections} property
* or the {@literal spring.data.gemfire.cache.server.max-connections} property
* in {@literal application.properties}.
*/
int maxConnections() default CacheServer.DEFAULT_MAX_CONNECTIONS;
/**
* Configures he maximum number of messages that can be enqueued in a client-queue.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_MAXIMUM_MESSAGE_COUNT
* Defaults to {@link CacheServer#DEFAULT_MAXIMUM_MESSAGE_COUNT}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.max-message-count} property
* or the {@literal spring.data.gemfire.cache.server.max-message-count} property
* in {@literal application.properties}.
*/
int maxMessageCount() default CacheServer.DEFAULT_MAXIMUM_MESSAGE_COUNT;
/**
* Configures the maximum number of threads allowed in this cache server to service client requests.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_MAX_THREADS
* Defaults to {@link CacheServer#DEFAULT_MAX_THREADS}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.max-threads} property
* or the {@literal spring.data.gemfire.cache.server.max-threads} property
* in {@literal application.properties}.
*/
int maxThreads() default CacheServer.DEFAULT_MAX_THREADS;
/**
* Configures the maximum amount of time between client pings.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS
* Defaults to {@link CacheServer#DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.max-time-between-pings} property
* or the {@literal spring.data.gemfire.cache.server.max-time-between-pings} property
* in {@literal application.properties}.
*/
int maxTimeBetweenPings() default CacheServer.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS;
/**
* Configures the time (in seconds ) after which a message in the client queue will expire.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_MESSAGE_TIME_TO_LIVE
* Defaults to {@link CacheServer#DEFAULT_MESSAGE_TIME_TO_LIVE}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.message-time-to-live} property
* or the {@literal spring.data.gemfire.cache.server.message-time-to-live} property
* in {@literal application.properties}.
*/
int messageTimeToLive() default CacheServer.DEFAULT_MESSAGE_TIME_TO_LIVE;
/**
* Configures the name of the Spring bean defined in the Spring application context.
* Configures the {@link String name} of the Spring bean defined in the Spring application context.
*
* Defaults to empty.
*
* This attribute is also used to resolve named {@link CacheServer} properties
* from {@literal application.properties} specific to the configuration of this {@link CacheServer} definition,
* therefore, this attribute must be specified when external configuration (e.g. {@literal application.properties})
* is used.
*/
String name() default "";
/**
* Configures the port on which this cache server listens for clients.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_PORT
* Defaults to {@link CacheServer#DEFAULT_PORT}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.port} property
* or the {@literal spring.data.gemfire.cache.server.port} property
* in {@literal application.properties}.
*/
int port() default CacheServer.DEFAULT_PORT;
/**
* Configures the configured buffer size of the socket connection for this CacheServer.
*
* @see org.apache.geode.cache.server.CacheServer#DEFAULT_SOCKET_BUFFER_SIZE
* Defaults to {@link CacheServer#DEFAULT_SOCKET_BUFFER_SIZE}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.socket-buffer-size} property
* or the {@literal spring.data.gemfire.cache.server.socket-buffer-size} property
* in {@literal application.properties}.
*/
int socketBufferSize() default CacheServer.DEFAULT_SOCKET_BUFFER_SIZE;
/**
* Configures the capacity of the client queue.
*
* @see org.apache.geode.cache.server.ClientSubscriptionConfig#DEFAULT_CAPACITY
* Defaults to {@link ClientSubscriptionConfig#DEFAULT_CAPACITY}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.subscription-capacity} property
* or the {@literal spring.data.gemfire.cache.server.subscription-capacity} property
* in {@literal application.properties}.
*/
int subscriptionCapacity() default ClientSubscriptionConfig.DEFAULT_CAPACITY;
/**
* Configures the disk store name for overflow.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.subscription-disk-store-name} property
* or the {@literal spring.data.gemfire.cache.server.subscription-disk-store-name} property
* in {@literal application.properties}.
*/
String subscriptionDiskStoreName() default "";
@@ -156,7 +213,22 @@ public @interface EnableCacheServer {
* Configures the eviction policy that is executed when capacity of the client queue is reached.
*
* Defaults to {@link SubscriptionEvictionPolicy#NONE}.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.subscription-eviction-policy} property
* or the {@literal spring.data.gemfire.cache.server.subscription-eviction-policy} property
* in {@literal application.properties}.
*/
SubscriptionEvictionPolicy subscriptionEvictionPolicy() default SubscriptionEvictionPolicy.NONE;
/**
* Configures the tcpNoDelay setting of sockets used to send messages to clients.
*
* TcpNoDelay is enabled by default.
*
* Use either the {@literal spring.data.gemfire.cache.server.<beanName>.tcp-no-delay} property
* or the {@literal spring.data.gemfire.cache.server.tcp-no-delay} property
* in {@literal application.properties}.
*/
boolean tcpNoDelay() default CacheServer.DEFAULT_TCP_NO_DELAY;
}

View File

@@ -17,6 +17,16 @@
package org.springframework.data.gemfire.config.annotation;
import static org.springframework.data.gemfire.config.annotation.DiskStoreConfiguration.DEFAULT_ALLOW_FORCE_COMPACTION;
import static org.springframework.data.gemfire.config.annotation.DiskStoreConfiguration.DEFAULT_AUTO_COMPACT;
import static org.springframework.data.gemfire.config.annotation.DiskStoreConfiguration.DEFAULT_COMPACTION_THRESHOLD;
import static org.springframework.data.gemfire.config.annotation.DiskStoreConfiguration.DEFAULT_DISK_USAGE_CRITICAL_PERCENTAGE;
import static org.springframework.data.gemfire.config.annotation.DiskStoreConfiguration.DEFAULT_DISK_USAGE_WARNING_PERCENTAGE;
import static org.springframework.data.gemfire.config.annotation.DiskStoreConfiguration.DEFAULT_MAX_OPLOG_SIZE;
import static org.springframework.data.gemfire.config.annotation.DiskStoreConfiguration.DEFAULT_QUEUE_SIZE;
import static org.springframework.data.gemfire.config.annotation.DiskStoreConfiguration.DEFAULT_TIME_INTERVAL;
import static org.springframework.data.gemfire.config.annotation.DiskStoreConfiguration.DEFAULT_WRITE_BUFFER_SIZE;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
@@ -24,14 +34,15 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.geode.cache.DiskStore;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.AliasFor;
/**
* The {@link EnableDiskStore} annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
* annotated application class to configure a single GemFire/Geode {@link org.apache.geode.cache.DiskStore} bean
* in the Spring context in which to persist or overflow data from 1 or more GemFire/Geode
* {@link org.apache.geode.cache.Region Regions}
* The {@link EnableDiskStore} annotation marks a Spring {@link Configuration @Configuration} annotated {@link Class}
* to configure a single GemFire/Geode {@link org.apache.geode.cache.DiskStore} bean in the Spring application context
* in which to persist or overflow data from 1 or more cache {@link org.apache.geode.cache.Region Regions}.
*
* @author John Blum
* @see org.apache.geode.cache.DiskStore
@@ -52,13 +63,20 @@ import org.springframework.core.annotation.AliasFor;
public @interface EnableDiskStore {
/**
* Name of the {@link org.apache.geode.cache.DiskStore}.
* Name of the {@link DiskStore}.
*
* Required!
*/
@AliasFor(attribute = "name")
String value() default "";
/**
* Name of the {@link org.apache.geode.cache.DiskStore}.
* Name of the {@link DiskStore}.
*
* Required!
*
* This value of this attribute is also used to resolve {@link DiskStore} specific properties defined in
* {@literal application.properties}.
*/
@AliasFor(attribute = "value")
String name() default "";
@@ -66,16 +84,24 @@ public @interface EnableDiskStore {
/**
* Set to true to allow disk compaction to be forced on this disk store.
*
* Default is {@literal false}.
* Defaults to {@literal false}.
*
* Use either the {@literal spring.data.gemfire.disk.store.<diskStoreName>.allow-force-compaction} property
* or the {@literal spring.data.gemfire.disk.store.allow-force-compaction} property
* in {@literal application.properties}.
*/
boolean allowForceCompaction() default false;
boolean allowForceCompaction() default DEFAULT_ALLOW_FORCE_COMPACTION;
/**
* Set to true to automatically compact the disk files.
*
* Default is {@literal false}.
* Defaults to {@literal true}.
*
* Use either the {@literal spring.data.gemfire.disk.store.<diskStoreName>.auto-compact} property
* or the {@literal spring.data.gemfire.disk.store.auto-compact} property
* in {@literal application.properties}.
*/
boolean autoCompact() default false;
boolean autoCompact() default DEFAULT_AUTO_COMPACT;
/**
* The threshold at which an oplog will become compactable. Until it reaches this threshold the oplog
@@ -84,13 +110,27 @@ public @interface EnableDiskStore {
* The threshold is a percentage in the range 0 to 100.
*
* Defaults to {@literal 50} percent.
*
* Use either the {@literal spring.data.gemfire.disk.store.<diskStoreName>.compaction-threshold} property
* or the {@literal spring.data.gemfire.disk.store.compaction-threshold} property
* in {@literal application.properties}.
*/
int compactionThreshold() default 50;
int compactionThreshold() default DEFAULT_COMPACTION_THRESHOLD;
/**
* File system directory location(s) in which the {@link org.apache.geode.cache.DiskStore} files are stored.
*
* Defaults to current working directory with 2 petabytes of storage capacity maximum size.
*
* Use either the {@literal spring.data.gemfire.disk.store.<diskStoreName>.directory[#].location},
* {@literal spring.data.gemfire.disk.store.<diskStoreName>.directory[#].size},
* {@literal spring.data.gemfire.disk.store.<diskStoreName>.directory.location},
* {@literal spring.data.gemfire.disk.store.<diskStoreName>.directory.size} properties,
* or the {@literal spring.data.gemfire.disk.store.directory[#].location}
* {@literal spring.data.gemfire.disk.store.directory[#].size},
* {@literal spring.data.gemfire.disk.store.directory.location},
* {@literal spring.data.gemfire.disk.store.directory.size} properties,
* in {@literal application.properties}.
*/
DiskDirectory[] diskDirectories() default {};
@@ -103,8 +143,12 @@ public @interface EnableDiskStore {
* Set to "0" (zero) to disable.
*
* Defaults to {@literal 99} percent.
*
* Use either the {@literal spring.data.gemfire.disk.store.<diskStoreName>.disk-usage-critical-percentage} property
* or the {@literal spring.data.gemfire.disk.store.disk-usage-critical-percentage} property
* in {@literal application.properties}.
*/
float diskUsageCriticalPercentage() default 99.0f;
float diskUsageCriticalPercentage() default DEFAULT_DISK_USAGE_CRITICAL_PERCENTAGE;
/**
* Disk usage above this threshold generates a warning message.
@@ -115,29 +159,45 @@ public @interface EnableDiskStore {
* Set to "0" (zero) to disable.
*
* Defaults to {@literal 90} percent.
*
* Use either the {@literal spring.data.gemfire.disk.store.<diskStoreName>.disk-usage-warning-percentage} property
* or the {@literal spring.data.gemfire.disk.store.disk-usage-warning-percentage} property
* in {@literal application.properties}.
*/
float diskUsageWarningPercentage() default 90.0f;
float diskUsageWarningPercentage() default DEFAULT_DISK_USAGE_WARNING_PERCENTAGE;
/**
* The maximum size, in megabytes, of an oplog (operation log) file.
*
* Defaults to {@literal 1024} MB.
*
* Use either the {@literal spring.data.gemfire.disk.store.<diskStoreName>.max-oplog-size} property
* or the {@literal spring.data.gemfire.disk.store.max-oplog-size} property
* in {@literal application.properties}.
*/
long maxOplogSize() default 1024L;
long maxOplogSize() default DEFAULT_MAX_OPLOG_SIZE;
/**
* Maximum number of operations that can be asynchronously queued to be written to disk.
*
* Defaults to {@literal 0} (unlimited).
*
* Use either the {@literal spring.data.gemfire.disk.store.<diskStoreName>.queue-size} property
* or the {@literal spring.data.gemfire.disk.store.queue-size} property
* in {@literal application.properties}.
*/
int queueSize() default 0;
int queueSize() default DEFAULT_QUEUE_SIZE;
/**
* The number of milliseconds that can elapse before unwritten data is written to disk.
*
* Defaults to {@literal 1000} ms.
*
* Use either the {@literal spring.data.gemfire.disk.store.<diskStoreName>.time-interval} property
* or the {@literal spring.data.gemfire.disk.store.time-interval} property
* in {@literal application.properties}.
*/
long timeInterval() default 1000L;
long timeInterval() default DEFAULT_TIME_INTERVAL;
/**
* The size of the write buffer that this disk store uses when writing data to disk.
@@ -146,8 +206,12 @@ public @interface EnableDiskStore {
* one direct memory buffer of this size.
*
* Defaults to {@literal 32768} bytes.
*
* Use either the {@literal spring.data.gemfire.disk.store.<diskStoreName>.write-buffer-size} property
* or the {@literal spring.data.gemfire.disk.store.write-buffer-size} property
* in {@literal application.properties}.
*/
int writeBufferSize() default 32768;
int writeBufferSize() default DEFAULT_WRITE_BUFFER_SIZE;
@interface DiskDirectory {

View File

@@ -17,6 +17,7 @@
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
@@ -24,16 +25,24 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The EnableHttpService annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
* annotated class to configure and enable GemFire/Geode's embedded HTTP service.
* The {@link EnableHttpService} annotation marks a Spring {@link Configuration @Configuration}
* annotated {@link Class} to configure and enable Pivotal GemFire/Apache Geode's embedded HTTP service.
*
* By using this annotation, this allows GemFire's embedded HTTP services, like Pulse, the Management REST API
* and the Developer REST API to be enabled.
* By using this {@link Annotation}, this enables the embedded HTTP services like Pulse, the Management REST API
* and the Developer REST API on startup.
*
* However, the embedded Pivotal GemFire/Apache Geode HTTP service and all dependent services (e.g. Pulse)
* can be enabled/disabled externally in {@literal application.properties} with
* the {@literal spring.data.gemfire.service.http.enabled} property even when this {@link Annotation} is present,
* thereby serving as a toggle.
*
* @author John Blum
* @see java.lang.annotation.Annotation
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.HttpServiceConfiguration
* @see <a href="http://geode.docs.pivotal.io/docs/rest_apps/book_intro.html">Developing REST Applications for Apache Geode</a>
* @since 1.9.0
@@ -53,6 +62,8 @@ public @interface EnableHttpService {
* and the Developer REST API service.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.service.http.bind-address} property in {@literal application.properties}.
*/
String bindAddress() default "";
@@ -64,6 +75,8 @@ public @interface EnableHttpService {
* and {@literal start-dev-rest-api} are both set to {@literal false}.
*
* Defaults to {@literal 7070}.
*
* Use the {@literal spring.data.gemfire.service.http.port} property in {@literal application.properties}.
*/
int port() default HttpServiceConfiguration.DEFAULT_HTTP_SERVICE_PORT;
@@ -77,15 +90,21 @@ public @interface EnableHttpService {
* {@link org.springframework.data.gemfire.config.annotation.EnableSsl.Component#HTTP}.
*
* Defaults to {@literal false}.
*
* Use the {@literal spring.data.gemfire.service.http.ssl-require-authentication} property
* in {@literal application.properties}.
*/
boolean sslRequireAuthentication() default false;
/**
* If set to true, then the developer REST API service will be started when cache is created.
* The REST service can be configured using {@literal http-service-port} and {@literal http-service-bind-address}
* GemFire System Properties.
* If set to {@literal true}, then the Developer REST API service will be started when the cache is created.
* The REST service can be configured using {@literal http-service-bind-address} and {@literal http-service-port}
* Pivotal GemFire/Apache Geode System Properties.
*
* Defaults to {@literal false}.
*
* Use the {@literal spring.data.gemfire.service.http.dev-rest-api.start} property
* in {@literal application.properties}.
*/
boolean startDeveloperRestApi() default false;

View File

@@ -17,6 +17,7 @@
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
@@ -24,13 +25,20 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.geode.distributed.Locator;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The EnableLocator annotation configures a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
* annotated class to start an embedded GemFire Locator service in this GemFire server/data node.
* The {@link EnableLocator} annotation configures a Spring {@link Configuration @Configuration} annotated {@link Class}
* to start an embedded Pivotal GemFire/Apache Geode {@link Locator} service in this cluster member.
*
* However, the embedded Pivotal GemFire/Apache Geode Locator service can be enabled/disabled externally
* in {@literal application.properties} with the {@literal spring.data.gemfire.service.http.enabled} property
* even when this {@link Annotation} is present, thereby serving as a toggle.
*
* @author John Blum
* @see java.lang.annotation.Annotation
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.LocatorConfiguration
* @since 1.9.0
@@ -47,7 +55,9 @@ public @interface EnableLocator {
* Configures the host/IP address on which the embedded Locator service will bind to for accepting connections
* from clients sending Locator requests.
*
* Default is {@literal localhost}.
* Defaults to {@literal localhost}.
*
* Use the {@literal spring.data.gemfire.locator.host} property in {@literal application.properties}.
*/
String host() default LocatorConfiguration.DEFAULT_HOST;
@@ -55,7 +65,9 @@ public @interface EnableLocator {
* Configures the port on which the embedded Locator service will bind to listening for client connections
* sending Locator requests.
*
* Default is {@literal 10334}.
* Defaults to {@literal 10334}.
*
* Use the {@literal spring.data.gemfire.locator.host} property in {@literal application.properties}.
*/
int port() default LocatorConfiguration.DEFAULT_LOCATOR_PORT;

View File

@@ -24,13 +24,16 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The EnableLogging annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
* annotated class to configure and enable GemFire/Geode system logging.
* The {@link EnableLogging} annotation marks a Spring {@link Configuration @Configuration} annotated {@link Class}
* to configure and enable Pivotal GemFire/Apache Geode system logging.
*
* @author John Blum
* @see java.lang.annotation.Annotation
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.LoggingConfiguration
* @since 1.9.0
*/
@@ -47,6 +50,9 @@ public @interface EnableLogging {
* are deleted, oldest first, until the total size is within the limit. If set to zero, disk space use is unlimited.
*
* Defaults to {@literal 0} MB.
*
* Use the {@literal spring.data.gemfire.logging.log-disk-space-limit} property
* in {@literal application.properties}.
*/
int logDiskSpaceLimit() default LoggingConfiguration.DEFAULT_LOG_DISK_SPACE_LIMIT;
@@ -54,6 +60,8 @@ public @interface EnableLogging {
* File to which a running system member writes log messages. Logs to standard out by default.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.logging.log-file} property in {@literal application.properties}.
*/
String logFile() default "";
@@ -62,6 +70,8 @@ public @interface EnableLogging {
* If set to 0, log rolling is disabled.
*
* Defaults to {@literal 0} MB.
*
* Use the {@literal spring.data.gemfire.logging.log-file-size-limit} property in {@literal application.properties}.
*/
int logFileSizeLimit() default LoggingConfiguration.DEFAULT_LOG_FILE_SIZE_LIMIT;
@@ -73,6 +83,8 @@ public @interface EnableLogging {
* {@literal error}, {@literal severe}, and {@literal none}.
*
* Defaults to {@literal config}.
*
* Use the {@literal spring.data.gemfire.logging.level} property in {@literal application.properties}.
*/
String logLevel() default "config";

View File

@@ -17,6 +17,7 @@
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
@@ -24,15 +25,22 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The EnableManager annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
* annotated class to configure, embed and start a GemFire/Geode Manager service in the GemFire/Geode Server.
* The {@link EnableManager} annotation marks a Spring {@link Configuration @Configuration} annotated {@link Class}
* to configure, embed and start a Pivotal GemFire/Apache Geode Manager service in this cluster member.
*
* Automatically sets {@literal jmx-manager} to {@literal true}.
* Automatically sets {@literal jmx-manager} to {@literal true} just by specifying this {@link Annotation}
* on your Spring application {@link Configuration @Configuration} annotated {@link Class}.
*
* However, the embedded Pivotal GemFire/Apache Geode Manager can be enabled/disabled externally
* in {@literal application.properties} by using the {@literal spring.data.gemfire.manager.enabled} property
* even when this {@link Annotation} is present, thereby serving as a toggle.
*
* @author John Blum
* @see java.lang.annotation.Annotation
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.ManagerConfiguration
* @since 1.9.0
@@ -54,6 +62,8 @@ public @interface EnableManager {
* is false or if {@literal jmx-manager-port} is zero.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.manager.access-file} property in {@literal application.properties}.
*/
String accessFile() default "";
@@ -63,6 +73,8 @@ public @interface EnableManager {
* non-HTTP connections. Ignored if JMX Manager is {@literal false} or {@literal jmx-manager-port} is zero.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.manager.bind-address} property in {@literal application.properties}.
*/
String bindAddress() default "";
@@ -73,6 +85,9 @@ public @interface EnableManager {
* {@literal jmx-manager} is {@literal false} or {@literal jmx-manager-port} is zero.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.manager.hostname-for-clients} property
* in {@literal application.properties}.
*/
String hostnameForClients() default "";
@@ -84,6 +99,8 @@ public @interface EnableManager {
* System property. Ignored if {@literal jmx-manager} is {@literal false} or {@literal jmx-manager-port} is zero.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.manager.password-file} property in {@literal application.properties}.
*/
String passwordFile() default "";
@@ -93,6 +110,8 @@ public @interface EnableManager {
* by the JVM for configuring access from remote JMX clients. Ignored if {@literal jmx-manager} is {@literal false}.
*
* Defaults to {@literal 1099}.
*
* Use the {@literal spring.data.gemfire.manager.port} property in {@literal application.properties}.
*/
int port() default ManagerConfiguration.DEFAULT_JMX_MANAGER_PORT;
@@ -103,6 +122,8 @@ public @interface EnableManager {
* to {@literal true}. Ignored if {@literal jmx-manager} is {@literal false}.
*
* Defaults to {@literal false}.
*
* Use the {@literal spring.data.gemfire.manager.start} property in {@literal application.properties}.
*/
boolean start() default false;
@@ -112,6 +133,8 @@ public @interface EnableManager {
* cause stale values to be seen by Gfsh and GemFire Pulse.
*
* Defaults to {@literal 2000} milliseconds.
*
* Use the {@literal spring.data.gemfire.manager.update-rate} property in {@literal application.properties}.
*/
int updateRate() default 2000;

View File

@@ -24,14 +24,17 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The EnableMcast annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
* annotated class to configure and enable GemFire/Geode's multi-cast networking support.
* The {@link EnableMcast} annotation marks a Spring {@link Configuration @Configuration} annotated {@link Class}
* to configure and enable Pivotal GemFire/Apache Geode's multi-cast networking features.
*
* @author John Blum
* @see org.springframework.data.gemfire.config.annotation.EnableMcast
* @see java.lang.annotation.Annotation
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.McastConfiguration
* @since 1.9.0
*/
@Target(ElementType.TYPE)

View File

@@ -17,6 +17,7 @@
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
@@ -24,16 +25,22 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The EnableMemcachedServer annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
* annotated class to start an embedded Memcached Server (Gemcached) service in the GemFire server/data node.
* The {@link EnableMemcachedServer} annotation marks a Spring {@link Configuration @Configuration}
* annotated {@link Class} to start an embedded Memcached Server (Gemcached) service in this cluster member.
*
* The Gemcached service implements the Memcached Server protocol enabling Memcached clients to connect to
* and communicate with Pivotal GemFire or Apache Geode servers.
*
* However, the embedded Pivotal GemFire/Apache Geode Memcached Service can be enabled/disabled externally
* in {@literal application.properties} by using the {@literal spring.data.gemfire.service.memcached.enabled} property
* even when this {@link Annotation} is present, thereby serving as a toggle.
*
* @author John Blum
* @see java.lang.annotation.Annotation
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.MemcachedServerConfiguration
* @since 1.9.0
@@ -51,6 +58,8 @@ public @interface EnableMemcachedServer {
* and starts the Gemcached server.
*
* Default to {@literal 11211}.
*
* Use the {@literal spring.data.gemfire.service.memcached.port} property in {@literal application.properties}.
*/
int port() default MemcachedServerConfiguration.DEFAULT_MEMCACHED_SERVER_PORT;
@@ -59,6 +68,8 @@ public @interface EnableMemcachedServer {
* If you omit this property, the ASCII protocol is used.
*
* Default to {@link MemcachedProtocol#ASCII}.
*
* Use the {@literal spring.data.gemfire.service.memcached.protocol} property in {@literal application.properties}.
*/
MemcachedProtocol protocol() default MemcachedProtocol.ASCII;

View File

@@ -24,14 +24,18 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.geode.cache.Region;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The EnableOffHeap annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
* annotated class to configure and enable Apache Geode Off-Heap Memory support and data storage
* in Geode's cache {@link org.apache.geode.cache.Region Regions}.
* The {@link EnableOffHeap} annotation marks a Spring {@link Configuration @Configuration} annotated {@link Class}
* to configure and enable Pivotal GemFire/Apache Geode Off-Heap Memory support and data storage
* in cache {@link org.apache.geode.cache.Region Regions}.
*
* @author John Blum
* @see java.lang.annotation.Annotation
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.OffHeapConfiguration
* @since 1.9.0
*/
@@ -44,7 +48,9 @@ import org.springframework.context.annotation.Import;
public @interface EnableOffHeap {
/**
* Specifies the size of off-heap memory in megabytes (m) or gigabytes (g). For example:
* Specifies the size of off-heap memory in megabytes (m) or gigabytes (g).
*
* For example:
*
* <pre>
* <code>
@@ -54,13 +60,17 @@ public @interface EnableOffHeap {
* </pre>
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.cache.off-heap-memory-size} property in {@literal application.properties}.
*/
String memorySize();
/**
* Idenfitied the Regions by name in which the off-heap memory setting will be applied.
* Identifies all the {@link Region Regions} by name in which the off-heap memory setting will be applied.
*
* Defaults to all Regions.
*
* Use the {@literal spring.data.gemfire.cache.region-names} property in {@literal application.properties}.
*/
String[] regionNames() default {};

View File

@@ -24,12 +24,17 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.AnnotationMetadata;
/**
* The EnablePdx annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
* annotated class to enable the GemFire PDX features and functionality in a GemFire server/data node
* or GemFire cache client application.
* The {@link EnablePdx} annotation marks a Spring {@link Configuration @Configuration} annotated {@link Class}
* to enable the Pivotal GemFire/Apache Geode PDX features and functionality in this peer cache, cluster member
* or cache client application.
*
* @author John Blum
* @see java.lang.annotation.Annotation
* @see org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration#configurePdx(AnnotationMetadata)
* @since 1.9.0
*/
@Target(ElementType.TYPE)
@@ -41,6 +46,8 @@ public @interface EnablePdx {
/**
* Configures the disk store that is used for PDX meta data.
*
* Use the {@literal spring.data.gemfire.pdx.disk-store-name} property in {@literal application.properties}.
*/
String diskStoreName() default "";
@@ -48,6 +55,8 @@ public @interface EnablePdx {
* Configures whether pdx ignores fields that were unread during deserialization.
*
* Default is {@literal false}.
*
* Use the {@literal spring.data.gemfire.pdx.ignore-unread-fields} property in {@literal application.properties}.
*/
boolean ignoreUnreadFields() default false;
@@ -55,6 +64,8 @@ public @interface EnablePdx {
* Configures whether the type metadata for PDX objects is persisted to disk.
*
* Default is {@literal false}.
*
* Use the {@literal spring.data.gemfire.pdx.persistent} property in {@literal application.properties}.
*/
boolean persistent() default false;
@@ -62,6 +73,8 @@ public @interface EnablePdx {
* Configures the object preference to {@link org.apache.geode.pdx.PdxInstance} type or {@link Object}.
*
* Default is {@literal false}.
*
* Use the {@literal spring.data.gemfire.pdx.read-serialized} property in {@literal application.properties}.
*/
boolean readSerialized() default false;

View File

@@ -43,6 +43,7 @@ import org.springframework.data.gemfire.GemfireUtils;
* @see org.apache.geode.cache.client.Pool
* @see org.apache.geode.cache.client.PoolFactory
* @see org.springframework.data.gemfire.config.annotation.AddPoolConfiguration
* @see org.springframework.data.gemfire.config.annotation.AddPoolsConfiguration
* @see org.springframework.data.gemfire.config.annotation.EnablePools
* @see org.springframework.data.gemfire.config.annotation.PoolConfigurer
* @since 1.9.0
@@ -58,27 +59,43 @@ public @interface EnablePool {
/**
* Configures the free connection timeout for this pool.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_FREE_CONNECTION_TIMEOUT
* Defaults to {@link PoolFactory#DEFAULT_FREE_CONNECTION_TIMEOUT}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.free-connection-timeout} property
* or the {@literal spring.data.gemfire.pool.free-connection-timeout} property
* in {@literal application.properties}.
*/
int freeConnectionTimeout() default PoolFactory.DEFAULT_FREE_CONNECTION_TIMEOUT;
/**
* Configures the amount of time a connection can be idle before expiring the connection.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_IDLE_TIMEOUT
* Defaults to {@link PoolFactory#DEFAULT_IDLE_TIMEOUT}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.idle-timeout} property
* or the {@literal spring.data.gemfire.pool.idle-timeout} property
* in {@literal application.properties}.
*/
long idleTimeout() default PoolFactory.DEFAULT_IDLE_TIMEOUT;
/**
* Configures the load conditioning interval for this pool.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_LOAD_CONDITIONING_INTERVAL
* Defaults to {@link PoolFactory#DEFAULT_LOAD_CONDITIONING_INTERVAL}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.load-conditioning-interval} property
* or the {@literal spring.data.gemfire.pool.load-conditioning-interval} property
* in {@literal application.properties}.
*/
int loadConditioningInterval() default PoolFactory.DEFAULT_LOAD_CONDITIONING_INTERVAL;
/**
* Configures the GemFire {@link org.apache.geode.distributed.Locator Locators} to which
* this cache client will connect.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.locators} property
* or the {@literal spring.data.gemfire.pool.locators} property
* in {@literal application.properties}.
*/
Locator[] locators() default {};
@@ -87,39 +104,62 @@ public @interface EnablePool {
* of GemFire Locators in the cluster.
*
* The {@link String} must be formatted as: 'host1[port], host2[port], ..., hostN[port]'.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.locators} property
* or the {@literal spring.data.gemfire.pool.locators} property
* in {@literal application.properties}.
*/
String locatorsString() default "";
/**
* Configures the max number of client to server connections that the pool will create.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_MAX_CONNECTIONS
* Defaults to {@link PoolFactory#DEFAULT_MAX_CONNECTIONS}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.max-connections} property
* or the {@literal spring.data.gemfire.pool.max-connections} property
* in {@literal application.properties}.
*/
int maxConnections() default PoolFactory.DEFAULT_MAX_CONNECTIONS;
/**
* Configures the minimum number of connections to keep available at all times.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_MIN_CONNECTIONS
* Defaults to {@link PoolFactory#DEFAULT_MIN_CONNECTIONS}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.min-connections} property
* or the {@literal spring.data.gemfire.pool.min-connections} property
* in {@literal application.properties}.
*/
int minConnections() default PoolFactory.DEFAULT_MIN_CONNECTIONS;
/**
* If set to true then the created pool can be used by multiple users.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_MULTIUSER_AUTHENTICATION
* Defaults to {@link PoolFactory#DEFAULT_MULTIUSER_AUTHENTICATION}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.multi-user-authentication} property
* or the {@literal spring.data.gemfire.pool.multi-user-authentication} property
* in {@literal application.properties}.
*/
boolean multiUserAuthentication() default PoolFactory.DEFAULT_MULTIUSER_AUTHENTICATION;
/**
* Specifies the name of the GemFire client {@link Pool}.
* 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
* (e.g. {@literal spring.data.gemfire.pool.<poolName>.max-connections} used in the resolution of {@link Pool}
* properties from {@literal application.properties} that are specific to this {@link Pool}.
*/
String name();
/**
* Configures how often to ping servers to verify that they are still alive.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_PING_INTERVAL
* Defaults to {@link PoolFactory#DEFAULT_PING_INTERVAL}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.ping-interval} property
* or the {@literal spring.data.gemfire.pool.ping-interval} property
* in {@literal application.properties}.
*/
long pingInterval() default PoolFactory.DEFAULT_PING_INTERVAL;
@@ -127,7 +167,11 @@ public @interface EnablePool {
* By default {@code prSingleHopEnabled} is {@literal true} in which case the client is aware of the location
* of partitions on servers hosting Regions with {@link org.apache.geode.cache.DataPolicy#PARTITION}.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_PR_SINGLE_HOP_ENABLED
* Defaults to {@link PoolFactory#DEFAULT_PR_SINGLE_HOP_ENABLED}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.pr-single-hop-enabled} property
* or the {@literal spring.data.gemfire.pool.pr-single-hop-enabled} property
* in {@literal application.properties}.
*/
boolean prSingleHopEnabled() default PoolFactory.DEFAULT_PR_SINGLE_HOP_ENABLED;
@@ -135,27 +179,43 @@ public @interface EnablePool {
* Configures the number of milliseconds to wait for a response from a server before timing out the operation
* and trying another server (if any are available).
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_READ_TIMEOUT
* Defaults to {@link PoolFactory#DEFAULT_READ_TIMEOUT}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.read-timeout} property
* or the {@literal spring.data.gemfire.pool.read-timeout} property
* in {@literal application.properties}.
*/
int readTimeout() default PoolFactory.DEFAULT_READ_TIMEOUT;
/**
* Configures the number of times to retry a request after timeout/exception.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_RETRY_ATTEMPTS
* Defaults to {@link PoolFactory#DEFAULT_RETRY_ATTEMPTS}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.retry-attempts} property
* or the {@literal spring.data.gemfire.pool.retry-attempts} property
* in {@literal application.properties}.
*/
int retryAttempts() default PoolFactory.DEFAULT_RETRY_ATTEMPTS;
/**
* Configures the group that all servers this pool connects to must belong to.
* Configures the group that all servers in which this pool connects to must belong to.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SERVER_GROUP
* Defaults to {@link PoolFactory#DEFAULT_SERVER_GROUP}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.server-group} property
* or the {@literal spring.data.gemfire.pool.server-group} property
* in {@literal application.properties}.
*/
String serverGroup() default PoolFactory.DEFAULT_SERVER_GROUP;
/**
* Configures the GemFire {@link org.apache.geode.cache.server.CacheServer CacheServers} to which
* this cache client will connect.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.servers} property
* or the {@literal spring.data.gemfire.pool.servers} property
* in {@literal application.properties}.
*/
Server[] servers() default {};
@@ -164,20 +224,32 @@ public @interface EnablePool {
* of GemFire Servers in the cluster.
*
* The {@link String} must be formatted as: 'host1[port], host2[port], ..., hostN[port]'.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.servers} property
* or the {@literal spring.data.gemfire.pool.servers} property
* in {@literal application.properties}.
*/
String serversString() default "";
/**
* Configures the socket buffer size for each connection made in this pool.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SOCKET_BUFFER_SIZE
* Defaults to {@link PoolFactory#DEFAULT_SOCKET_BUFFER_SIZE}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.socket-buffer-size} property
* or the {@literal spring.data.gemfire.pool.socket-buffer-size} property
* in {@literal application.properties}.
*/
int socketBufferSize() default PoolFactory.DEFAULT_SOCKET_BUFFER_SIZE;
/**
* Configures how often to send client statistics to the server.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_STATISTIC_INTERVAL
* Defaults to {@link PoolFactory#DEFAULT_STATISTIC_INTERVAL}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.statistic-interval} property
* or the {@literal spring.data.gemfire.pool.statistic-interval} property
* in {@literal application.properties}.
*/
int statisticInterval() default PoolFactory.DEFAULT_STATISTIC_INTERVAL;
@@ -185,14 +257,22 @@ public @interface EnablePool {
* Configures the interval in milliseconds to wait before sending acknowledgements to the cache server
* for events received from the server subscriptions.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_ACK_INTERVAL
* Defaults to {@link PoolFactory#DEFAULT_SUBSCRIPTION_ACK_INTERVAL}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.subscription-ack-interval} property
* or the {@literal spring.data.gemfire.pool.subscription-ack-interval} property
* in {@literal application.properties}.
*/
int subscriptionAckInterval() default PoolFactory.DEFAULT_SUBSCRIPTION_ACK_INTERVAL;
/**
* If set to true then the created pool will have server-to-client subscriptions enabled.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_ENABLED
* Defaults to {@link PoolFactory#DEFAULT_SUBSCRIPTION_ENABLED}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.subscription-enabled} property
* or the {@literal spring.data.gemfire.pool.subscription-enabled} property
* in {@literal application.properties}.
*/
boolean subscriptionEnabled() default PoolFactory.DEFAULT_SUBSCRIPTION_ENABLED;
@@ -200,21 +280,33 @@ public @interface EnablePool {
* Configures the messageTrackingTimeout attribute which is the time-to-live period, in milliseconds,
* for subscription events the client has received from the server.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT
* Defaults to {@link PoolFactory#DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.subscription-message-tracking-timeout} property
* or the {@literal spring.data.gemfire.pool.subscription-message-tracking-timeout} property
* in {@literal application.properties}.
*/
int subscriptionMessageTrackingTimeout() default PoolFactory.DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT;
/**
* Configures the redundancy level for this pools server-to-client subscriptions.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_REDUNDANCY
* Defaults to {@link PoolFactory#DEFAULT_SUBSCRIPTION_REDUNDANCY}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.subscription-redundancy} property
* or the {@literal spring.data.gemfire.pool.subscription-redundancy} property
* in {@literal application.properties}.
*/
int subscriptionRedundancy() default PoolFactory.DEFAULT_SUBSCRIPTION_REDUNDANCY;
/**
* Configures the thread local connections policy for this pool.
*
* @see org.apache.geode.cache.client.PoolFactory#DEFAULT_THREAD_LOCAL_CONNECTIONS
* Defaults to {@link PoolFactory#DEFAULT_THREAD_LOCAL_CONNECTIONS}.
*
* Use either the {@literal spring.data.gemfire.pool.<poolName>.thread-local-connections} property
* or the {@literal spring.data.gemfire.pool.thread-local-connections} property
* in {@literal application.properties}.
*/
boolean threadLocalConnections() default PoolFactory.DEFAULT_THREAD_LOCAL_CONNECTIONS;

View File

@@ -17,6 +17,7 @@
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
@@ -24,16 +25,23 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The EnableRedisServer annotation marks a Spring {@link org.springframework.context.annotation.Configuration}
* class to embed the Redis service in the GemFire server-side data member node.
* The {@link EnableRedisServer} annotation marks a Spring {@link Configuration @Configuration} annotated {@link Class}
* to embed the Redis service in this cluster member.
*
* The Redis service implements the Redis server protocol enabling Redis clients to connect and speak
* to Pivotal GemFire or Apache Geode.
* The Redis service implements the Redis server protocol enabling Redis clients to connect to and inter-operate with
* Pivotal GemFire or Apache Geode.
*
* However, the embedded Pivotal GemFire/Apache Geode Redis Service can be enabled/disabled externally
* in {@literal application.properties} by using the {@literal spring.data.gemfire.service.redis.enabled} property
* even when this {@link Annotation} is present, thereby serving as a toggle.
*
* @author John Blum
* @see java.lang.annotation.Annotation
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.MemcachedServerConfiguration
* @since 1.9.0
*/
@@ -49,6 +57,8 @@ public @interface EnableRedisServer {
* Configures the Network bind-address on which the Redis server will accept connections.
*
* Defaults to {@literal localhost}.
*
* Use the {@literal spring.data.gemfire.service.redis.bind-address} property in {@literal application.properties}.
*/
String bindAddress() default "";
@@ -56,6 +66,8 @@ public @interface EnableRedisServer {
* Configures the Network port on which the Redis server will listen for Redis client connections.
*
* Defaults to {@literal 6379}.
*
* Use the {@literal spring.data.gemfire.service.redis.port} property in {@literal application.properties}.
*/
int port() default RedisServerConfiguration.DEFAULT_REDIS_PORT;

View File

@@ -25,15 +25,16 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.geode.security.AuthInitialize;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The {@link EnableSecurity} annotation marks a Spring {@link org.springframework.context.annotation.Configuration}
* annotated class to configure and enable Apache Geode's Security features for authentication, authorization
* The {@link EnableSecurity} annotation marks a Spring {@link Configuration @Configuration} annotated {@link Class}
* to configure and enable Pivotal GemFire/Apache Geode's Security features for authentication, authorization
* and post processing.
*
* @author John Blum
* @see GeodeIntegratedSecurityConfiguration
* @see java.lang.annotation.Annotation
* @see org.apache.geode.security.AuthInitialize
* @see org.apache.geode.security.SecurityManager
* @see org.apache.geode.security.PostProcessor
@@ -55,6 +56,9 @@ public @interface EnableSecurity {
* which obtains credentials for clients.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.security.client.authentication-initializer} property
* in {@literal application.properties}.
*/
String clientAuthenticationInitializer() default "";
@@ -63,6 +67,9 @@ public @interface EnableSecurity {
* credentials for peers in a distributed system.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.security.peer.authentication-initializer} property
* in {@literal application.properties}.
*/
String peerAuthenticationInitializer() default "";
@@ -81,6 +88,8 @@ public @interface EnableSecurity {
* Use this Annotation attribute if you are uncertain whether the application class is on the classpath or not.
*
* Default is unset.
*
* Use the {@literal spring.data.gemfire.security.manager.class-name} property in {@literal application.properties}.
*/
String securityManagerClassName() default "";
@@ -101,6 +110,9 @@ public @interface EnableSecurity {
* Use this Annotation attribute if you are uncertain whether the application class is on the classpath or not.
*
* Default is unset.
*
* Use the {@literal spring.data.gemfire.security.postprocessor.class-name} property
* in {@literal application.properties}.
*/
String securityPostProcessorClassName() default "";
@@ -109,6 +121,9 @@ public @interface EnableSecurity {
* the Apache Shiro Security Framework to secure Apache Geode.
*
* Default is unset.
*
* Use the {@literal spring.data.gemfire.security.shiro.ini-resource-path} property
* in {@literal application.properties}.
*/
String shiroIniResourcePath() default "";

View File

@@ -24,13 +24,18 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The EnableSsl class...
* The {@link EnableSsl} annotation marks a Spring {@link Configuration @Configuration} annotated {@link Class}
* to configure and enable Pivotal GemFire/Apache Geode's TCP/IP Socket SSL.
*
* @author John Blum
* @since 1.0.0
* @see java.lang.annotation.Annotation
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.SslConfiguration
* @since 1.9.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@@ -45,13 +50,21 @@ public @interface EnableSsl {
* uses any ciphers that are enabled by default in the configured JSSE provider.
*
* Defaults to {@literal any}.
*
* Use either the {@literal spring.data.gemfire.security.ssl.<component>.ciphers} property
* or the {@literal spring.data.gemfire.security.ssl.ciphers} property
* in {@literal application.properties}.
*/
String ciphers() default "any";
/**
* A list of GemFire components in which SSL will be enabled.
* An array of Pivotal GemFire/Apache Geode Components in which SSL can be enabled.
*
* Defaults to {@link org.springframework.data.gemfire.config.annotation.EnableSsl.Component#CLUSTER}
* Defaults to {@link EnableSsl.Component#CLUSTER}.
*
* The value(s) for this attribute are used to configure cluster-wide
* (e.g. {@literal spring.data.gemfire.security.ssl.cluster.keystore} SSL properties
* or individual component {e.g. {@literal spring.data.gemfire.security.ssl.locator.keystore}} SSL properties.
*/
Component[] components() default { Component.CLUSTER };
@@ -59,6 +72,10 @@ public @interface EnableSsl {
* Pathname to the keystore used for SSL communications.
*
* Defaults to unset.
*
* Use either the {@literal spring.data.gemfire.security.ssl.<component>.keystore} property
* or the {@literal spring.data.gemfire.security.ssl.keystore} property
* in {@literal application.properties}.
*/
String keystore() default "";
@@ -66,15 +83,24 @@ public @interface EnableSsl {
* Password to access the keys in the keystore used in SSL communications.
*
* Defaults to unset.
*
* Use either the {@literal spring.data.gemfire.security.ssl.<component>.keystore-password} property
* or the {@literal spring.data.gemfire.security.ssl.keystore-password} property
* in {@literal application.properties}.
*/
String keystorePassword() default "";
/**
* TODO change to an enum?
*
* Identifies the type of keystore used in SSL communications. For example, JKS, PKCS11, etc.
*
* Defaults to unset.
*
* Use either the {@literal spring.data.gemfire.security.ssl.<component>.keystore-type} property
* or the {@literal spring.data.gemfire.security.ssl.keystore-type} property
* in {@literal application.properties}.
*/
// TODO change to a enum?
String keystoreType() default "";
/**
@@ -82,6 +108,10 @@ public @interface EnableSsl {
* uses any protocol that is enabled by default in the configured JSSE provider.
*
* Defaults to {@literal any}.
*
* Use either the {@literal spring.data.gemfire.security.ssl.<component>.protocols} property
* or the {@literal spring.data.gemfire.security.ssl.protocols} property
* in {@literal application.properties}.
*/
String protocols() default "any";
@@ -90,6 +120,10 @@ public @interface EnableSsl {
* clients and servers, gateways, etc.
*
* Defaults to {@literal true}.
*
* Use either the {@literal spring.data.gemfire.security.ssl.<component>.require-authentication} property
* or the {@literal spring.data.gemfire.security.ssl.require-authentication} property
* in {@literal application.properties}.
*/
boolean requireAuthentication() default true;
@@ -97,6 +131,10 @@ public @interface EnableSsl {
* Pathname to the truststore used in SSL communications.
*
* Defaults to unset.
*
* Use either the {@literal spring.data.gemfire.security.ssl.<component>.truststore} property
* or the {@literal spring.data.gemfire.security.ssl.truststore} property
* in {@literal application.properties}.
*/
String truststore() default "";
@@ -104,10 +142,15 @@ public @interface EnableSsl {
* Password to access the keys in the truststore used in SSL communications.
*
* Defaults to unset.
*
* Use either the {@literal spring.data.gemfire.security.ssl.<component>.truststore-password} property
* or the {@literal spring.data.gemfire.security.ssl.truststore-password} property
* in {@literal application.properties}.
*/
String truststorePassword() default "";
enum Component {
CLUSTER("cluster"),
GATEWAY("gateway"),
HTTP("http-service"),
@@ -117,10 +160,17 @@ public @interface EnableSsl {
private final String prefix;
/* (non-Javadoc) */
Component(String prefix) {
this.prefix = prefix;
}
/**
* Returns a {@link String} representation of this enumerated value.
*
* @return a {@link String} describing this enumerated value.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return prefix;

View File

@@ -24,15 +24,18 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The EnableStatistics annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
* annotated class to configure and enable statistics and runtime metrics of a running GemFire/Geode system.
* The {@link EnableStatistics} annotation marks a Spring {@link Configuration @Configuration} annotated {@link Class}
* to configure and enable statistics and runtime metrics of a running Pivotal GemFire/Apache Geode system.
*
* Sets {@literal statistic-sampling-enabled} to {@literal true}.
*
* @author John Blum
* @see java.lang.annotation.Annotation
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.StatisticsConfiguration
* @since 1.9.0
*/
@@ -50,6 +53,9 @@ public @interface EnableStatistics {
* disk space use is unlimited.
*
* Defaults to {@literal 0} MB.
*
* Use the {@literal spring.data.gemfire.stats.archive-disk-space-limit} property
* in {@literal application.properties}.
*/
int archiveDiskSpaceLimit() default StatisticsConfiguration.DEFAULT_ARCHIVE_DISK_SPACE_LIMIT;
@@ -58,6 +64,8 @@ public @interface EnableStatistics {
* An empty string disables archiving. Adding .gz suffix to the file name causes it to be compressed.
*
* Defaults to unset.
*
* Use the {@literal spring.data.gemfire.stats.archive-file} property in {@literal application.properties}.
*/
String archiveFile() default "";
@@ -67,6 +75,9 @@ public @interface EnableStatistics {
* file size is unlimited.
*
* Defaults to {@literal 0} MB.
*
* Use the {@literal spring.data.gemfire.stats.archive-file-size-limit} property
* in {@literal application.properties}.
*/
int archiveFileSizeLimit() default StatisticsConfiguration.DEFAULT_ARCHIVE_FILE_SIZE_LIMIT;
@@ -75,6 +86,9 @@ public @interface EnableStatistics {
* Disabled by default for performance reasons and not recommended for production environments.
*
* Defaults to {@literal false}.
*
* Use the {@literal spring.data.gemfire.stats.enable-time-statistics} property
* in {@literal application.properties}.
*/
boolean enableTimeStatistics() default StatisticsConfiguration.DEFAULT_ENABLE_TIME_STATISTICS;
@@ -84,6 +98,8 @@ public @interface EnableStatistics {
* Valid values are in the range 100..60000.
*
* Defaults to {@literal 1000} milliseconds.
*
* Use the {@literal spring.data.gemfire.stats.sample-rate} property in {@literal application.properties}.
*/
long sampleRate() default StatisticsConfiguration.DEFAULT_STATISTIC_SAMPLE_RATE;

View File

@@ -41,14 +41,24 @@ public class GeodeIntegratedSecurityConfiguration extends EmbeddedServiceConfigu
protected static final String SECURITY_SHIRO_INIT = "security-shiro-init";
/**
* @inheritDoc
* Returns the {@link EnableSecurity} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableSecurity} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableSecurity
*/
@Override
protected Class getAnnotationType() {
return EnableSecurity.class;
}
/* (non-Javadoc) */
/**
* Determines whether Pivotal GemFire/Apache Geode's Apache Shiro Security Framework support is enabled
* or available.
*
* @return a boolean value indicating whether Pivotal GemFire/Apache Geode's Apache Shiro Security Framework
* support is enabled or available.
* @see #isShiroSecurityNotConfigured()
*/
protected boolean isShiroSecurityConfigured() {
try {
// NOTE experimental...
@@ -60,38 +70,51 @@ public class GeodeIntegratedSecurityConfiguration extends EmbeddedServiceConfigu
}
}
/* (non-Javadoc) */
/**
* Determines whether Pivotal GemFire/Apache Geode's Apache Shiro Security Framework support is enabled
* or available.
*
* @return a boolean value indicating whether Pivotal GemFire/Apache Geode's Apache Shiro Security Framework
* support is enabled or available.
* @see #isShiroSecurityConfigured()
*/
protected boolean isShiroSecurityNotConfigured() {
return !isShiroSecurityConfigured();
}
/**
* @inheritDoc
*/
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
PropertiesBuilder gemfireProperties = new PropertiesBuilder();
PropertiesBuilder gemfireProperties = PropertiesBuilder.create();
gemfireProperties.setProperty(SECURITY_CLIENT_AUTH_INIT,
annotationAttributes.get("clientAuthenticationInitializer"));
resolveProperty(securityProperty("client.authentication-initializer"),
(String) annotationAttributes.get("clientAuthenticationInitializer")));
if (isShiroSecurityNotConfigured()) {
gemfireProperties.setPropertyIfNotDefault(SECURITY_MANAGER,
annotationAttributes.get("securityManagerClass"), Void.class);
gemfireProperties.setProperty(SECURITY_MANAGER, annotationAttributes.get("securityManagerClassName"));
gemfireProperties.setProperty(SECURITY_MANAGER,
resolveProperty(securityProperty("manager.class-name"),
(String) annotationAttributes.get("securityManagerClassName")));
gemfireProperties.setProperty(SECURITY_SHIRO_INIT, annotationAttributes.get("shiroIniResourcePath"));
gemfireProperties.setProperty(SECURITY_SHIRO_INIT,
resolveProperty(securityProperty("shiro.ini-resource-path"),
(String) annotationAttributes.get("shiroIniResourcePath")));
}
gemfireProperties.setProperty(SECURITY_PEER_AUTH_INIT,
annotationAttributes.get("peerAuthenticationInitializer"));
resolveProperty(securityProperty("peer.authentication-initializer"),
(String) annotationAttributes.get("peerAuthenticationInitializer")));
gemfireProperties.setPropertyIfNotDefault(SECURITY_POST_PROCESSOR,
annotationAttributes.get("securityPostProcessorClass"), Void.class);
gemfireProperties.setProperty(SECURITY_POST_PROCESSOR,
annotationAttributes.get("securityPostProcessorClassName"));
resolveProperty(securityProperty("postprocessor.class-name"),
(String) annotationAttributes.get("securityPostProcessorClassName")));
return gemfireProperties.build();
}

View File

@@ -18,17 +18,20 @@
package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
* The HttpServiceConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
* that applies additional GemFire/Geode configuration by way of GemFire/Geode System properties to configure
* GemFire/Geode's embeded HTTP service and services.
* The {@link HttpServiceConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} that applies
* additional configuration by way of Pivotal GemFire/Apache Geode {@link Properties} to configure
* Pivotal GemFire/Apache Geode's embedded HTTP service and dependent services (e.g. Pulse).
*
* @author John Blum
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.data.gemfire.config.annotation.EnableHttpService
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @see <a href="http://geode.docs.pivotal.io/docs/rest_apps/book_intro.html">Developing REST Applications for Apache Geode</a>
@@ -41,7 +44,12 @@ public class HttpServiceConfiguration extends EmbeddedServiceConfigurationSuppor
public static final int DEFAULT_HTTP_SERVICE_PORT = 7070;
/* (non-Javadoc) */
/**
* Returns the {@link EnableHttpService} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableHttpService} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableHttpService
*/
@Override
protected Class getAnnotationType() {
return EnableHttpService.class;
@@ -50,19 +58,35 @@ public class HttpServiceConfiguration extends EmbeddedServiceConfigurationSuppor
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
PropertiesBuilder gemfireProperties = PropertiesBuilder.create();
gemfireProperties.setProperty("http-service-bind-address", annotationAttributes.get("bindAddress"));
return Optional.of(resolveProperty(httpServiceProperty("enabled"), Boolean.TRUE))
.filter(Boolean.TRUE::equals)
.map(enabled -> {
gemfireProperties.setPropertyIfNotDefault("http-service-port",
annotationAttributes.get("port"), DEFAULT_HTTP_SERVICE_PORT);
PropertiesBuilder gemfireProperties = PropertiesBuilder.create();
gemfireProperties.setPropertyIfNotDefault("http-service-ssl-require-authentication",
annotationAttributes.get("sslRequireAuthentication"), DEFAULT_HTTP_SERVICE_SSL_REQUIRE_AUTHENTICATION);
gemfireProperties.setProperty("http-service-bind-address",
resolveProperty(httpServiceProperty("bind-address"),
(String) annotationAttributes.get("bindAddress")));
gemfireProperties.setPropertyIfNotDefault("start-dev-rest-api",
annotationAttributes.get("startDeveloperRestApi"), DEFAULT_HTTP_SERVICE_START_DEVELOPER_REST_API);
gemfireProperties.setPropertyIfNotDefault("http-service-port",
resolveProperty(httpServiceProperty("port"),
(Integer) annotationAttributes.get("port")),
DEFAULT_HTTP_SERVICE_PORT);
return gemfireProperties.build();
gemfireProperties.setPropertyIfNotDefault("http-service-ssl-require-authentication",
resolveProperty(httpServiceProperty("ssl-require-authentication"),
(Boolean) annotationAttributes.get("sslRequireAuthentication")),
DEFAULT_HTTP_SERVICE_SSL_REQUIRE_AUTHENTICATION);
gemfireProperties.setPropertyIfNotDefault("start-dev-rest-api",
resolveProperty(httpServiceProperty("dev-rest-api.start"),
(Boolean) annotationAttributes.get("startDeveloperRestApi")),
DEFAULT_HTTP_SERVICE_START_DEVELOPER_REST_API);
return gemfireProperties.build();
})
.orElseGet(Properties::new);
}
}

View File

@@ -18,19 +18,24 @@
package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import org.apache.geode.distributed.Locator;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.gemfire.GemfireUtils;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
* The LocatorConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
* that applies additional GemFire configuration by way of GemFire System properties to configure
* an embedded GemFire Locator.
* The {@link LocatorConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} that applies
* additional configuration by way of Pivotal GemFire/Apache Geode {@link Properties} to configure
* an embedded {@link Locator}.
*
* @author John Blum
* @see EnableLocator
* @see org.apache.geode.distributed.Locator
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.data.gemfire.config.annotation.EnableLocator
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
*/
@@ -38,20 +43,37 @@ public class LocatorConfiguration extends EmbeddedServiceConfigurationSupport {
protected static final int DEFAULT_LOCATOR_PORT = GemfireUtils.DEFAULT_LOCATOR_PORT;
protected static final String START_LOCATOR_GEMFIRE_SYSTEM_PROPERTY_NAME = "start-locator";
protected static final String START_LOCATOR_GEMFIRE_PROPERTY_NAME = "start-locator";
/**
* Returns the {@link EnableLocator} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableLocator} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableLocator
*/
@Override
protected Class getAnnotationType() {
return EnableLocator.class;
}
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
String host = resolveHost((String) annotationAttributes.get("host"));
int port = resolvePort((Integer) annotationAttributes.get("port"), DEFAULT_LOCATOR_PORT);
return PropertiesBuilder.create()
.setProperty(START_LOCATOR_GEMFIRE_SYSTEM_PROPERTY_NAME, String.format("%s[%d]", host, port))
.build();
return Optional.of(resolveProperty(locatorProperty("enabled"), Boolean.TRUE))
.filter(Boolean.TRUE::equals)
.map(enabled -> {
String host = resolveHost(resolveProperty(locatorProperty("host"),
(String) annotationAttributes.get("host")));
int port = resolvePort(resolveProperty(locatorProperty("port"),
(Integer) annotationAttributes.get("port")), DEFAULT_LOCATOR_PORT);
return PropertiesBuilder.create()
.setProperty(START_LOCATOR_GEMFIRE_PROPERTY_NAME, String.format("%s[%d]", host, port))
.build();
}).orElseGet(Properties::new);
}
}

View File

@@ -20,15 +20,17 @@ package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Properties;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
* The LoggingConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
* that applies additional GemFire/Geode configuration by way of GemFire/Geode System properties to configure
* GemFire/Geode logging.
* The {@link LoggingConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} that applies
* additional configuration using Pivotal GemFire/Apache Geode {@link Properties} to configure
* Pivotal GemFire/Apache Geode logging.
*
* @author John Blum
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.data.gemfire.config.annotation.EnableLogging
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
@@ -40,7 +42,12 @@ public class LoggingConfiguration extends EmbeddedServiceConfigurationSupport {
public static final String DEFAULT_LOG_LEVEL = "config";
/* (non-Javadoc) */
/**
* Returns the {@link EnableLogging} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableLogging} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableLogging
*/
@Override
protected Class getAnnotationType() {
return EnableLogging.class;
@@ -49,18 +56,24 @@ public class LoggingConfiguration extends EmbeddedServiceConfigurationSupport {
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
PropertiesBuilder gemfireProperties = PropertiesBuilder.create();
gemfireProperties.setPropertyIfNotDefault("log-disk-space-limit",
annotationAttributes.get("logDiskSpaceLimit"), DEFAULT_LOG_DISK_SPACE_LIMIT);
resolveProperty(loggingProperty("log-disk-space-limit"),
(Integer) annotationAttributes.get("logDiskSpaceLimit")), DEFAULT_LOG_DISK_SPACE_LIMIT);
gemfireProperties.setProperty("log-file", annotationAttributes.get("logFile"));
gemfireProperties.setProperty("log-file",
resolveProperty(loggingProperty("log-file"),
(String) annotationAttributes.get("logFile")));
gemfireProperties.setPropertyIfNotDefault("log-file-size-limit",
annotationAttributes.get("logFileSizeLimit"), DEFAULT_LOG_FILE_SIZE_LIMIT);
resolveProperty(loggingProperty("log-file-size-limit"),
(Integer) annotationAttributes.get("logFileSizeLimit")), DEFAULT_LOG_FILE_SIZE_LIMIT);
gemfireProperties.setPropertyIfNotDefault("log-level",
annotationAttributes.get("logLevel"), DEFAULT_LOG_LEVEL);
resolveProperty(loggingProperty("level"),
(String) annotationAttributes.get("logLevel")), DEFAULT_LOG_LEVEL);
return gemfireProperties.build();
}

View File

@@ -20,16 +20,18 @@ package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Properties;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
* The ManagerConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
* that applies additional GemFire configuration using GemFire System {@link Properties} to configure
* an embedded GemFire Manager.
* The {@link ManagerConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} that applies
* additional configuration using Pivotal GemFire/Apache Geode {@link Properties} to configure an embedded Manager
* in this cluster member.
*
* @author John Blum
* @see EnableManager
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.data.gemfire.config.annotation.EnableManager
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
*/
@@ -37,24 +39,52 @@ public class ManagerConfiguration extends EmbeddedServiceConfigurationSupport {
protected static final int DEFAULT_JMX_MANAGER_PORT = 1099;
/**
* Returns the {@link EnableManager} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableManager} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableManager
*/
@Override
protected Class getAnnotationType() {
return EnableManager.class;
}
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
PropertiesBuilder gemfireProperties = PropertiesBuilder.create();
gemfireProperties.setProperty("jmx-manager", Boolean.TRUE.toString());
gemfireProperties.setProperty("jmx-manager-access-file", annotationAttributes.get("accessFile"));
gemfireProperties.setProperty("jmx-manager-bind-address", annotationAttributes.get("bindAddress"));
gemfireProperties.setProperty("jmx-manager-hostname-for-clients", annotationAttributes.get("hostnameForClients"));
gemfireProperties.setProperty("jmx-manager-password-file", annotationAttributes.get("passwordFile"));
gemfireProperties.setProperty("jmx-manager",
resolveProperty(managerProperty("enabled"), Boolean.TRUE));
gemfireProperties.setProperty("jmx-manager-access-file",
resolveProperty(managerProperty("access-file"),
(String) annotationAttributes.get("accessFile")));
gemfireProperties.setProperty("jmx-manager-bind-address",
resolveProperty(managerProperty("bind-address"),
(String) annotationAttributes.get("bindAddress")));
gemfireProperties.setProperty("jmx-manager-hostname-for-clients",
resolveProperty(managerProperty("hostname-for-clients"),
(String) annotationAttributes.get("hostnameForClients")));
gemfireProperties.setProperty("jmx-manager-password-file",
resolveProperty(managerProperty("password-file"),
(String) annotationAttributes.get("passwordFile")));
gemfireProperties.setProperty("jmx-manager-port",
resolvePort((Integer) annotationAttributes.get("port"), DEFAULT_JMX_MANAGER_PORT));
gemfireProperties.setProperty("jmx-manager-start", annotationAttributes.get("start"));
gemfireProperties.setProperty("jmx-manager-update-rate", annotationAttributes.get("updateRate"));
resolvePort(resolveProperty(managerProperty("port"),
(Integer) annotationAttributes.get("port")), DEFAULT_JMX_MANAGER_PORT));
gemfireProperties.setProperty("jmx-manager-start",
resolveProperty(managerProperty("start"), (Boolean) annotationAttributes.get("start")));
gemfireProperties.setProperty("jmx-manager-update-rate",
resolveProperty(managerProperty("update-rate"),
(Integer) annotationAttributes.get("updateRate")));
return gemfireProperties.build();
}

View File

@@ -44,35 +44,43 @@ public class McastConfiguration extends EmbeddedServiceConfigurationSupport {
public static final String DEFAULT_MCAST_FLOW_CONTROL = "1048576,0.25,5000";
/**
* {@inheritDoc}
* Returns the {@link EnableMcast} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableMcast} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableMcast
*/
@Override
protected Class getAnnotationType() {
return EnableMcast.class;
}
/**
* {@inheritDoc}
*/
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
PropertiesBuilder gemfireProperties = PropertiesBuilder.create();
gemfireProperties.unsetProperty("locators");
gemfireProperties.setPropertyIfNotDefault("mcast-address",
annotationAttributes.get("address"), DEFAULT_MCAST_ADDRESS);
resolveProperty(propertyName("mcast.address"),
(String) annotationAttributes.get("address")), DEFAULT_MCAST_ADDRESS);
gemfireProperties.setPropertyIfNotDefault("mcast-flow-control",
annotationAttributes.get("flowControl"), DEFAULT_MCAST_FLOW_CONTROL);
resolveProperty(propertyName("mcast.flow-control"),
(String) annotationAttributes.get("flowControl")), DEFAULT_MCAST_FLOW_CONTROL);
gemfireProperties.setPropertyIfNotDefault("mcast-port", annotationAttributes.get("port"), DEFAULT_MCAST_PORT);
gemfireProperties.setPropertyIfNotDefault("mcast-port",
resolveProperty(propertyName("mcast.port"),
(Integer) annotationAttributes.get("port")), DEFAULT_MCAST_PORT);
gemfireProperties.setPropertyIfNotDefault("mcast-recv-buffer-size",
annotationAttributes.get("receiveBufferSize"), DEFAULT_MCAST_RECEIVE_BUFFER_SIZE);
resolveProperty(propertyName("mcast.receive-buffer-size"),
(Integer) annotationAttributes.get("receiveBufferSize")), DEFAULT_MCAST_RECEIVE_BUFFER_SIZE);
gemfireProperties.setPropertyIfNotDefault("mcast-send-buffer-size",
annotationAttributes.get("sendBufferSize"), DEFAULT_MCAST_SEND_BUFFER_SIZE);
resolveProperty(propertyName("mcast.send-buffer-size"),
(Integer) annotationAttributes.get("sendBufferSize")), DEFAULT_MCAST_SEND_BUFFER_SIZE);
return gemfireProperties.build();
}

View File

@@ -18,17 +18,20 @@
package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
* The MemcachedServerConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
* that applies additional GemFire configuration by way of GemFire System properties to configure
* an embedded Memcached server.
* The {@link MemcachedServerConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} that applies
* additional configuration using Pivotal GemFire/Apache Geode {@link Properties} to configure
* an embedded Memcached server in this cluster member.
*
* @author John Blum
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.data.gemfire.config.annotation.EnableMemcachedServer
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
@@ -37,17 +40,35 @@ public class MemcachedServerConfiguration extends EmbeddedServiceConfigurationSu
protected static final int DEFAULT_MEMCACHED_SERVER_PORT = 11211;
/**
* Returns the {@link EnableMemcachedServer} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableMemcachedServer} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableMemcachedServer
*/
@Override
protected Class getAnnotationType() {
return EnableMemcachedServer.class;
}
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
return PropertiesBuilder.create()
.setProperty("memcached-port", resolvePort((Integer) annotationAttributes.get("port"),
DEFAULT_MEMCACHED_SERVER_PORT))
.setProperty("memcached-protocol", annotationAttributes.get("protocol"))
.build();
return Optional.of(resolveProperty(memcachedServiceProperty("enabled"), Boolean.TRUE))
.filter(Boolean.TRUE::equals)
.map(enabled ->
PropertiesBuilder.create()
.setProperty("memcached-port",
resolvePort(resolveProperty(memcachedServiceProperty("port"),
(Integer) annotationAttributes.get("port")), DEFAULT_MEMCACHED_SERVER_PORT))
.setProperty("memcached-protocol",
resolveProperty(memcachedServiceProperty("protocol"),
EnableMemcachedServer.MemcachedProtocol.class,
(EnableMemcachedServer.MemcachedProtocol) annotationAttributes.get("protocol")))
.build()
).orElseGet(Properties::new);
}
}

View File

@@ -17,10 +17,14 @@
package org.springframework.data.gemfire.config.annotation;
import static java.util.Arrays.stream;
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
@@ -33,6 +37,7 @@ import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.GenericRegionFactoryBean;
import org.springframework.data.gemfire.LocalRegionFactoryBean;
@@ -40,22 +45,27 @@ import org.springframework.data.gemfire.PartitionedRegionFactoryBean;
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
import org.springframework.data.gemfire.util.ArrayUtils;
import org.springframework.data.gemfire.util.CollectionUtils;
import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
* The OffHeapConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
* capable of enabling GemFire cache {@link Region Regions} to use Off-Heap memory for data storage.
* The {@link OffHeapConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} capable of
* enabling Pivotal GemFire/Apache Geode cache {@link Region Regions} to use Off-Heap memory for data storage.
*
* @author John Blum
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.data.gemfire.config.annotation.EnableOffHeap
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
*/
public class OffHeapConfiguration extends EmbeddedServiceConfigurationSupport {
/* (non-Javadoc) */
/**
* Returns the {@link EnableOffHeap} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableOffHeap} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableOffHeap
*/
@Override
protected Class getAnnotationType() {
return EnableOffHeap.class;
@@ -66,10 +76,11 @@ public class OffHeapConfiguration extends EmbeddedServiceConfigurationSupport {
protected void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
Map<String, Object> annotationAttributes, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
OffHeapBeanFactoryPostProcessor.class);
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(OffHeapBeanFactoryPostProcessor.class);
builder.addConstructorArgValue(annotationAttributes.get("regionNames"));
builder.addConstructorArgValue(resolveProperty(cacheProperty("region-names"),
String[].class, (String[]) annotationAttributes.get("regionNames")));
registry.registerBeanDefinition(generateBeanName(OffHeapBeanFactoryPostProcessor.class),
builder.getBeanDefinition());
@@ -78,17 +89,19 @@ public class OffHeapConfiguration extends EmbeddedServiceConfigurationSupport {
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
PropertiesBuilder gemfireProperties = PropertiesBuilder.create();
gemfireProperties.setProperty("off-heap-memory-size", annotationAttributes.get("memorySize"));
return gemfireProperties.build();
return PropertiesBuilder.create()
.setProperty("off-heap-memory-size",
resolveProperty(cacheProperty("off-heap-memory-size"),
(String) annotationAttributes.get("memorySize")))
.build();
}
/* (non-Javadoc) */
@SuppressWarnings("unused")
protected static class OffHeapBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
protected static final Set<String> REGION_FACTORY_BEAN_TYPES = new HashSet<String>(5);
protected static final Set<String> REGION_FACTORY_BEAN_TYPES = new HashSet<>(5);
static {
REGION_FACTORY_BEAN_TYPES.add(ClientRegionFactoryBean.class.getName());
@@ -101,7 +114,7 @@ public class OffHeapConfiguration extends EmbeddedServiceConfigurationSupport {
private final Set<String> regionNames;
protected OffHeapBeanFactoryPostProcessor(String[] regionNames) {
this(CollectionUtils.asSet(ArrayUtils.nullSafeArray(regionNames, String.class)));
this(CollectionUtils.asSet(nullSafeArray(regionNames, String.class)));
}
protected OffHeapBeanFactoryPostProcessor(Set<String> regionNames) {
@@ -110,13 +123,14 @@ public class OffHeapConfiguration extends EmbeddedServiceConfigurationSupport {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition bean = beanFactory.getBeanDefinition(beanName);
if (isTargetedRegionBean(beanName, bean, beanFactory)) {
bean.getPropertyValues().addPropertyValue("offHeap", true);
}
}
stream(nullSafeArray(beanFactory.getBeanDefinitionNames(), String.class)).forEach(beanName -> {
Optional.ofNullable(beanFactory.getBeanDefinition(beanName))
.filter(bean -> isTargetedRegionBean(beanName, bean, beanFactory))
.ifPresent(bean ->
bean.getPropertyValues().addPropertyValue("offHeap", true));
});
}
boolean isTargetedRegionBean(String beanName, BeanDefinition bean,
@@ -135,14 +149,17 @@ public class OffHeapConfiguration extends EmbeddedServiceConfigurationSupport {
}
Collection<String> getBeanNames(String beanName, BeanDefinition bean, BeanFactory beanFactory) {
Collection<String> beanNames = new HashSet<String>();
Collection<String> beanNames = new HashSet<>();
beanNames.add(beanName);
Collections.addAll(beanNames, beanFactory.getAliases(beanName));
PropertyValue regionName = bean.getPropertyValues().getPropertyValue("regionName");
if (regionName != null) {
Object regionNameValue = regionName.getValue();
if (regionNameValue != null) {

View File

@@ -35,10 +35,12 @@ import org.springframework.data.gemfire.support.GemfireBeanFactoryLocator;
* instance in a Spring Data GemFire based application.
*
* @author John Blum
* @see org.apache.geode.cache.control.ResourceManager
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.PeerCacheConfiguration
* @see org.apache.geode.cache.control.ResourceManager
* @see org.springframework.data.gemfire.support.GemfireBeanFactoryLocator
* @since 1.9.0
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@@ -53,14 +55,18 @@ public @interface PeerCacheApplication {
/**
* Indicates whether the "copy on read" is enabled for this cache.
*
* Default is {@literal false}.
* Defaults to {@literal false}.
*
* Use {@literal spring.data.gemfire.cache.copy-on-read} property in {@literal application.properties}.
*/
boolean copyOnRead() default false;
/**
* Configures the percentage of heap at or above which the cache is considered in danger of becoming inoperable.
*
* @see org.apache.geode.cache.control.ResourceManager#DEFAULT_CRITICAL_PERCENTAGE
* Defaults to {@link ResourceManager#DEFAULT_CRITICAL_PERCENTAGE}.
*
* Use {@literal spring.data.gemfire.cache.critical-heap-percentage} property in {@literal application.properties}.
*/
float criticalHeapPercentage() default ResourceManager.DEFAULT_CRITICAL_PERCENTAGE;
@@ -69,7 +75,10 @@ public @interface PeerCacheApplication {
* after it has been forced out of the distributed system by a network partition event or has otherwise been
* shunned by other members. Use this property to enable the auto-reconnect behavior.
*
* Default is {@literal false}.
* Defaults to {@literal false}.
*
* Use {@literal spring.data.gemfire.cache.peer.enable-auto-reconnect} property
* in {@literal application.properties}.
*/
boolean enableAutoReconnect() default false;
@@ -77,34 +86,43 @@ public @interface PeerCacheApplication {
* Configures the percentage of heap at or above which the eviction should begin on Regions configured
* for HeapLRU eviction.
*
* @see org.apache.geode.cache.control.ResourceManager#DEFAULT_EVICTION_PERCENTAGE
* Defaults to {@link ResourceManager#DEFAULT_EVICTION_PERCENTAGE}.
*
* Use {@literal spring.data.gemfire.cache.eviction-heap-percentage} property in {@literal application.properties}.
*/
float evictionHeapPercentage() default ResourceManager.DEFAULT_EVICTION_PERCENTAGE;
/**
* Configures the list of GemFire Locators defining the cluster to which this GemFire cache data node
* should connect.
* Configures the list of Locators defining the cluster to which this Spring cache application will connect.
*
* Use {@literal spring.data.gemfire.cache.peer.locators} property in {@literal application.properties}.
*/
String locators() default "";
/**
* Configures the length, in seconds, of distributed lock leases obtained by this cache.
*
* Default is {@literal 120} seconds.
* Defaults to {@literal 120} seconds.
*
* Use {@literal spring.data.gemfire.cache.peer.lock-lease} property in {@literal application.properties}.
*/
int lockLease() default 120;
/**
* Configures the number of seconds a cache operation will wait to obtain a distributed lock lease.
*
* Default is {@literal 60} seconds.
* Defaults to {@literal 60} seconds.
*
* Use {@literal spring.data.gemfire.cache.peer.lock-timeout} property in {@literal application.properties}.
*/
int lockTimeout() default 60;
/**
* Configures the log level used to output log messages at GemFire cache runtime.
*
* Default is {@literal config}.
* Defaults to {@literal config}.
*
* Use {@literal spring.data.gemfire.cache.log-level} property in {@literal application.properties}.
*/
String logLevel() default PeerCacheConfiguration.DEFAULT_LOG_LEVEL;
@@ -112,21 +130,28 @@ public @interface PeerCacheApplication {
* Configures the frequency (in seconds) at which a message will be sent by the primary cache-server to all
* the secondary cache-server nodes to remove the events which have already been dispatched from the queue.
*
* Default is {@literal 1} second.
* Defaults to {@literal 1} second.
*
* Use {@literal spring.data.gemfire.cache.peer.message-sync-interval} property
* in {@literal application.properties}.
*/
int messageSyncInterval() default 1;
/**
* Configures the name of this GemFire member in the cluster (distributed system).
*
* Default is {@literal SpringBasedPeerCacheApplication}.
* Defaults to {@literal SpringBasedPeerCacheApplication}.
*
* Use {@literal spring.data.gemfire.cache.name} property in {@literal application.properties}.
*/
String name() default PeerCacheConfiguration.DEFAULT_NAME;
/**
* Configures the number of seconds a cache get operation can spend searching for a value before it times out.
*
* Default is {@literal 300} seconds.
* Defaults to {@literal 300} seconds, or 5 minutes.
*
* Use {@literal spring.data.gemfire.cache.peer.search-timeout} property in {@literal application.properties}.
*/
int searchTimeout() default 300;
@@ -136,6 +161,8 @@ public @interface PeerCacheApplication {
* created in a non-Spring managed, GemFire context.
*
* Defaults to {@literal false}.
*
* Use {@literal spring.data.gemfire.use-bean-factory-locator} property in {@literal application.properties}.
*/
boolean useBeanFactoryLocator() default false;
@@ -143,7 +170,10 @@ public @interface PeerCacheApplication {
* Configures whether this GemFire cache member node would pull it's configuration meta-data
* from the cluster-based Cluster Configuration service.
*
* Default is {@literal false}.
* Defaults to {@literal false}.
*
* Use {@literal spring.data.gemfire.cache.peer.use-cluster-configuration} property
* in {@literal application.properties}.
*/
boolean useClusterConfiguration() default false;

View File

@@ -32,6 +32,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.util.StringUtils;
/**
* Spring {@link Configuration} class used to construct, configure and initialize a peer {@link Cache} instance
@@ -139,16 +140,31 @@ public class PeerCacheConfiguration extends AbstractCacheConfiguration {
Map<String, Object> peerCacheApplicationAttributes =
importMetadata.getAnnotationAttributes(getAnnotationTypeName());
setEnableAutoReconnect(Boolean.TRUE.equals(peerCacheApplicationAttributes.get("enableAutoReconnect")));
setLockLease((Integer) peerCacheApplicationAttributes.get("lockLease"));
setLockTimeout((Integer) peerCacheApplicationAttributes.get("lockTimeout"));
setMessageSyncInterval((Integer) peerCacheApplicationAttributes.get("messageSyncInterval"));
setSearchTimeout((Integer) peerCacheApplicationAttributes.get("searchTimeout"));
setUseClusterConfiguration(Boolean.TRUE.equals(peerCacheApplicationAttributes.get("useClusterConfiguration")));
setEnableAutoReconnect(resolveProperty(cachePeerProperty("enable-auto-reconnect"),
Boolean.TRUE.equals(peerCacheApplicationAttributes.get("enableAutoReconnect"))));
setLockLease(resolveProperty(cachePeerProperty("lock-lease"),
(Integer) peerCacheApplicationAttributes.get("lockLease")));
setLockTimeout(resolveProperty(cachePeerProperty("lock-timeout"),
(Integer) peerCacheApplicationAttributes.get("lockTimeout")));
setMessageSyncInterval(resolveProperty(cachePeerProperty("message-sync-interval"),
(Integer) peerCacheApplicationAttributes.get("messageSyncInterval")));
setSearchTimeout(resolveProperty(cachePeerProperty("search-timeout"),
(Integer) peerCacheApplicationAttributes.get("searchTimeout")));
setUseClusterConfiguration(resolveProperty(cachePeerProperty("use-cluster-configuration"),
Boolean.TRUE.equals(peerCacheApplicationAttributes.get("useClusterConfiguration"))));
Optional.ofNullable((String) peerCacheApplicationAttributes.get("locators"))
.filter(PeerCacheConfiguration::hasValue)
.ifPresent(this::setLocators);
Optional.ofNullable(resolveProperty(cachePeerProperty("locators"), (String) null))
.filter(StringUtils::hasText)
.ifPresent(this::setLocators);
}
}

View File

@@ -18,17 +18,20 @@
package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
* The RedisServerConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
* that applies additional GemFire configuration by way of GemFire System properties to configure
* The {@link RedisServerConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} that applies
* additional configuration using Pivotal GemFire/Apache Geode {@link Properties} to configure
* an embedded Redis server.
*
* @author John Blum
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.data.gemfire.config.annotation.EnableRedisServer
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
@@ -37,16 +40,34 @@ public class RedisServerConfiguration extends EmbeddedServiceConfigurationSuppor
protected static final int DEFAULT_REDIS_PORT = 6379;
/**
* Returns the {@link EnableRedisServer} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableRedisServer} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableRedisServer
*/
@Override
protected Class getAnnotationType() {
return EnableRedisServer.class;
}
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
return PropertiesBuilder.create()
.setProperty("redis-bind-address", annotationAttributes.get("bindAddress"))
.setProperty("redis-port", resolvePort((Integer)annotationAttributes.get("port"), DEFAULT_REDIS_PORT))
.build();
return Optional.ofNullable(resolveProperty(redisServiceProperty("enabled"), Boolean.TRUE))
.filter(Boolean.TRUE::equals)
.map(enabled ->
PropertiesBuilder.create()
.setProperty("redis-bind-address",
resolveProperty(redisServiceProperty("bind-address"),
(String) annotationAttributes.get("bindAddress")))
.setProperty("redis-port",
resolvePort(resolveProperty(redisServiceProperty("port"),
(Integer) annotationAttributes.get("port")), DEFAULT_REDIS_PORT))
.build()
).orElseGet(Properties::new);
}
}

View File

@@ -17,48 +17,102 @@
package org.springframework.data.gemfire.config.annotation;
import static java.util.Arrays.stream;
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
import java.util.Arrays;
import java.util.Map;
import java.util.Properties;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
import org.springframework.data.gemfire.util.PropertiesBuilder;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* The SslConfiguration class...
* The {@link SslConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} that applies
* additional configuration using Pivotal GemFire/Apache Geode {@link Properties} to configure SSL.
*
* @author John Blum
* @since 1.0.0
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.data.gemfire.config.annotation.EnableSsl
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
*/
public class SslConfiguration extends EmbeddedServiceConfigurationSupport {
/**
* Returns the {@link EnableSsl} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableSsl} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableSsl
*/
@Override
protected Class getAnnotationType() {
return EnableSsl.class;
}
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
PropertiesBuilder gemfireProperties = new PropertiesBuilder();
PropertiesBuilder gemfireProperties = PropertiesBuilder.create();
EnableSsl.Component[] components = (EnableSsl.Component[]) annotationAttributes.get("components");
Assert.notNull(components, "GemFire SSL enabled components cannot be null");
for (EnableSsl.Component component : components) {
gemfireProperties
.setProperty(String.format("%s-ssl-ciphers", component), annotationAttributes.get("ciphers"))
.setProperty(String.format("%s-ssl-enabled", component), Boolean.TRUE.toString())
.setProperty(String.format("%s-ssl-keystore", component), annotationAttributes.get("keystore"))
.setProperty(String.format("%s-ssl-keystore-password", component), annotationAttributes.get("keystorePassword"))
.setProperty(String.format("%s-ssl-keystore-type", component), annotationAttributes.get("keystoreType"))
.setProperty(String.format("%s-ssl-protocols", component), annotationAttributes.get("protocols"))
.setProperty(String.format("%s-ssl-require-authentication", component),
Boolean.TRUE.equals(annotationAttributes.get("requireAuthentication")))
.setProperty(String.format("%s-ssl-truststore", component), annotationAttributes.get("truststore"))
.setProperty(String.format("%s-ssl-truststore-password", component), annotationAttributes.get("truststorePassword"));
if (ObjectUtils.isEmpty(components)) {
logWarning("SSL will not be configured; No SSL enabled Components %s were specified",
Arrays.toString(EnableSsl.Component.values()));
}
stream(nullSafeArray(components, EnableSsl.Component.class)).forEach(component ->
gemfireProperties.setProperty(String.format("%s-ssl-ciphers", component),
resolveProperty(componentSslProperty(component.toString(), "ciphers"),
resolveProperty(sslProperty("ciphers"),
(String) annotationAttributes.get("ciphers"))))
.setProperty(String.format("%s-ssl-enabled", component),
resolveProperty(componentSslProperty(component.toString(), "enabled"),
resolveProperty(sslProperty("enabled"), true)))
.setProperty(String.format("%s-ssl-keystore", component),
resolveProperty(componentSslProperty(component.toString(), "keystore"),
resolveProperty(sslProperty("keystore"),
(String) annotationAttributes.get("keystore"))))
.setProperty(String.format("%s-ssl-keystore-password", component),
resolveProperty(componentSslProperty(component.toString(), "keystore-password"),
resolveProperty(sslProperty("keystore-password"),
(String) annotationAttributes.get("keystorePassword"))))
.setProperty(String.format("%s-ssl-keystore-type", component),
resolveProperty(componentSslProperty(component.toString(), "keystore-type"),
resolveProperty(sslProperty("keystore-type"),
(String) annotationAttributes.get("keystoreType"))))
.setProperty(String.format("%s-ssl-protocols", component),
resolveProperty(componentSslProperty(component.toString(), "protocols"),
resolveProperty(sslProperty("protocols"),
(String) annotationAttributes.get("protocols"))))
.setProperty(String.format("%s-ssl-require-authentication", component),
resolveProperty(componentSslProperty(component.toString(), "require-authentication"),
resolveProperty(sslProperty("require-authentication"),
Boolean.TRUE.equals(annotationAttributes.get("requireAuthentication")))))
.setProperty(String.format("%s-ssl-truststore", component),
resolveProperty(componentSslProperty(component.toString(), "truststore"),
resolveProperty(sslProperty("truststore"),
(String) annotationAttributes.get("truststore"))))
.setProperty(String.format("%s-ssl-truststore-password", component),
resolveProperty(componentSslProperty(component.toString(), "truststore-password"),
resolveProperty(sslProperty("truststore-password"),
(String) annotationAttributes.get("truststorePassword"))))
);
return gemfireProperties.build();
}
}

View File

@@ -20,15 +20,17 @@ package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Properties;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
* The StatisticsConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
* that applies additional GemFire/Geode configuration by way of GemFire/Geode System properties to configure
* GemFire/Geode Statistics.
* The {@link StatisticsConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} that applies
* additional configuration using Pivotal GemFire/Apache Geode {@link Properties} to configure
* Pivotal GemFire/Apache Geode Statistics.
*
* @author John Blum
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @see org.springframework.data.gemfire.config.annotation.EnableStatistics
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
@@ -41,7 +43,12 @@ public class StatisticsConfiguration extends EmbeddedServiceConfigurationSupport
public static final int DEFAULT_ARCHIVE_FILE_SIZE_LIMIT = 0;
public static final int DEFAULT_STATISTIC_SAMPLE_RATE = 1000;
/* (non-Javadoc) */
/**
* Returns the {@link EnableStatistics} {@link java.lang.annotation.Annotation} {@link Class} type.
*
* @return the {@link EnableStatistics} {@link java.lang.annotation.Annotation} {@link Class} type.
* @see org.springframework.data.gemfire.config.annotation.EnableStatistics
*/
@Override
protected Class getAnnotationType() {
return EnableStatistics.class;
@@ -50,23 +57,31 @@ public class StatisticsConfiguration extends EmbeddedServiceConfigurationSupport
/* (non-Javadoc) */
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
PropertiesBuilder gemfireProperties = new PropertiesBuilder();
gemfireProperties.setProperty("statistic-sampling-enabled", true);
gemfireProperties.setProperty("statistic-sampling-enabled",
resolveProperty(statsProperty("sampling-enabled"), true));
gemfireProperties.setPropertyIfNotDefault("archive-disk-space-limit",
annotationAttributes.get("archiveDiskSpaceLimit"), DEFAULT_ARCHIVE_DISK_SPACE_LIMIT);
resolveProperty(statsProperty("archive-disk-space-limit"),
(Integer) annotationAttributes.get("archiveDiskSpaceLimit")), DEFAULT_ARCHIVE_DISK_SPACE_LIMIT);
gemfireProperties.setProperty("statistic-archive-file",
resolveProperty(statsProperty("archive-file"),
(String) annotationAttributes.get("archiveFile")));
gemfireProperties.setPropertyIfNotDefault("archive-file-size-limit",
annotationAttributes.get("archiveFileSizeLimit"), DEFAULT_ARCHIVE_FILE_SIZE_LIMIT);
resolveProperty(statsProperty("archive-file-size-limit"),
(Integer) annotationAttributes.get("archiveFileSizeLimit")), DEFAULT_ARCHIVE_FILE_SIZE_LIMIT);
gemfireProperties.setProperty("enable-time-statistics",
Boolean.TRUE.equals(annotationAttributes.get("enableTimeStatistics")));
gemfireProperties.setProperty("statistic-archive-file", annotationAttributes.get("archiveFile"));
resolveProperty(statsProperty("enable-time-statistics"),
Boolean.TRUE.equals(annotationAttributes.get("enableTimeStatistics"))));
gemfireProperties.setPropertyIfNotDefault("statistic-sample-rate",
annotationAttributes.get("sampleRate"), DEFAULT_STATISTIC_SAMPLE_RATE);
resolveProperty(statsProperty("sample-rate"),
(Long) annotationAttributes.get("sampleRate")), DEFAULT_STATISTIC_SAMPLE_RATE);
return gemfireProperties.build();
}

View File

@@ -17,22 +17,30 @@
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.newIllegalStateException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.expression.BeanFactoryAccessor;
import org.springframework.context.expression.EnvironmentAccessor;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.env.Environment;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
@@ -49,22 +57,31 @@ import org.springframework.util.StringUtils;
* @see org.springframework.beans.factory.BeanClassLoaderAware
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.beans.factory.InitializingBean
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory
* @see org.springframework.beans.factory.support.AbstractBeanDefinition
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
* @see org.springframework.context.EnvironmentAware
* @see org.springframework.context.expression.BeanFactoryAccessor
* @see org.springframework.context.expression.EnvironmentAccessor
* @see org.springframework.core.env.Environment
* @see org.springframework.expression.EvaluationContext
* @since 1.9.0
*/
@SuppressWarnings("unused")
public abstract class AbstractAnnotationConfigSupport
implements BeanClassLoaderAware, BeanFactoryAware, InitializingBean {
implements BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware {
protected static final String SPRING_DATA_GEMFIRE_PROPERTY_PREFIX = "spring.data.gemfire.";
private BeanFactory beanFactory;
private ClassLoader beanClassLoader;
private EvaluationContext evaluationContext;
private Environment environment;
private final EvaluationContext evaluationContext;
private final Log log;
/**
* Determines whether the given {@link Object} has value. The {@link Object} is valuable
@@ -99,19 +116,38 @@ public abstract class AbstractAnnotationConfigSupport
return StringUtils.hasText(value);
}
@Override
public void afterPropertiesSet() throws Exception {
this.evaluationContext = newEvaluationContext();
/**
* Constructs a new instance of {@link AbstractAnnotationConfigSupport}.
*
* @see #AbstractAnnotationConfigSupport(BeanFactory)
*/
public AbstractAnnotationConfigSupport() {
this(null);
}
/**
* Constructs a new instance of {@link AbstractAnnotationConfigSupport}.
*
* @param beanFactory reference to the Spring {@link BeanFactory}.
* @see org.springframework.beans.factory.BeanFactory
* @see #newEvaluationContext(BeanFactory)
*/
public AbstractAnnotationConfigSupport(BeanFactory beanFactory) {
this.evaluationContext = newEvaluationContext(beanFactory);
this.log = newLog();
}
/**
* Constructs, configures and initializes a new instance of an {@link EvaluationContext}.
*
* @param beanFactory reference to the Spring {@link BeanFactory}.
* @return a new {@link EvaluationContext}.
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.expression.EvaluationContext
* @see #beanFactory()
*/
protected EvaluationContext newEvaluationContext() {
protected EvaluationContext newEvaluationContext(BeanFactory beanFactory) {
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
evaluationContext.addPropertyAccessor(new BeanFactoryAccessor());
@@ -119,15 +155,37 @@ public abstract class AbstractAnnotationConfigSupport
evaluationContext.addPropertyAccessor(new MapAccessor());
evaluationContext.setTypeLocator(new StandardTypeLocator(beanClassLoader()));
Optional.ofNullable(beanFactory())
.filter(beanFactory -> beanFactory instanceof ConfigurableBeanFactory)
.map(beanFactory -> ((ConfigurableBeanFactory) beanFactory).getConversionService())
.ifPresent(conversionService ->
evaluationContext.setTypeConverter(new StandardTypeConverter(conversionService)));
configureTypeConverter(evaluationContext, beanFactory);
return evaluationContext;
}
/* (non-Javadoc) */
private void configureTypeConverter(EvaluationContext evaluationContext, BeanFactory beanFactory) {
Optional.ofNullable(evaluationContext)
.filter(evalContext -> evalContext instanceof StandardEvaluationContext)
.ifPresent(evalContext ->
Optional.ofNullable(beanFactory)
.filter(it -> it instanceof ConfigurableBeanFactory)
.map(it -> ((ConfigurableBeanFactory) it).getConversionService())
.ifPresent(conversionService ->
((StandardEvaluationContext) evalContext).setTypeConverter(
new StandardTypeConverter(conversionService)))
);
}
/**
* Constructs a new instance of {@link Log} to log statements printed by Spring Data GemFire/Geode.
*
* @return a new instance of {@link Log}.
* @see org.apache.commons.logging.LogFactory#getLog(Class)
* @see org.apache.commons.logging.Log
*/
protected Log newLog() {
return LogFactory.getLog(getClass());
}
/**
* Returns the cache application {@link java.lang.annotation.Annotation} type pertaining to this configuration.
*
@@ -186,6 +244,7 @@ public abstract class AbstractAnnotationConfigSupport
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
configureTypeConverter(evaluationContext(), beanFactory);
}
/**
@@ -200,6 +259,28 @@ public abstract class AbstractAnnotationConfigSupport
.orElseThrow(() -> newIllegalStateException("BeanFactory is required"));
}
/**
* Sets a reference to the Spring {@link Environment}.
*
* @param environment Spring {@link Environment}.
* @see org.springframework.context.EnvironmentAware#setEnvironment(Environment)
* @see org.springframework.core.env.Environment
*/
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* Returns a reference to the Spring {@link Environment}.
*
* @return a reference to the Spring {@link Environment}.
* @see org.springframework.core.env.Environment
*/
protected Environment environment() {
return this.environment;
}
/**
*
* @return
@@ -208,6 +289,116 @@ public abstract class AbstractAnnotationConfigSupport
return this.evaluationContext;
}
/**
* Returns a reference to the {@link Log} used by this class to log {@link String messages}.
*
* @return a reference to the {@link Log} used by this class to log {@link String messages}.
* @see org.apache.commons.logging.Log
*/
protected Log getLog() {
return this.log;
}
/**
* Logs the {@link String message} formatted with the array of {@link Object arguments} at debug level.
*
* @param message {@link String} containing the message to log.
* @param args array of {@link Object arguments} used to format the {@code message}.
* @see #logDebug(Supplier)
*/
protected void logDebug(String message, Object... args) {
logDebug(() -> String.format(message, args));
}
/**
* Logs the {@link String message} supplied by the given {@link Supplier} at debug level.
*
* @param message {@link Supplier} containing the {@link String message} and arguments to log.
* @see org.apache.commons.logging.Log#isDebugEnabled()
* @see org.apache.commons.logging.Log#debug(Object)
* @see #getLog()
*/
protected void logDebug(Supplier<String> message) {
Optional.ofNullable(getLog())
.filter(Log::isDebugEnabled)
.ifPresent(log -> log.debug(message.get()));
}
/**
* Logs the {@link String message} formatted with the array of {@link Object arguments} at info level.
*
* @param message {@link String} containing the message to log.
* @param args array of {@link Object arguments} used to format the {@code message}.
* @see #logInfo(Supplier)
*/
protected void logInfo(String message, Object... args) {
logInfo(() -> String.format(message, args));
}
/**
* Logs the {@link String message} supplied by the given {@link Supplier} at info level.
*
* @param message {@link Supplier} containing the {@link String message} and arguments to log.
* @see org.apache.commons.logging.Log#isInfoEnabled()
* @see org.apache.commons.logging.Log#info(Object)
* @see #getLog()
*/
protected void logInfo(Supplier<String> message) {
Optional.ofNullable(getLog())
.filter(Log::isInfoEnabled)
.ifPresent(log -> log.info(message.get()));
}
/**
* Logs the {@link String message} formatted with the array of {@link Object arguments} at warn level.
*
* @param message {@link String} containing the message to log.
* @param args array of {@link Object arguments} used to format the {@code message}.
* @see #logWarning(Supplier)
*/
protected void logWarning(String message, Object... args) {
logWarning(() -> String.format(message, args));
}
/**
* Logs the {@link String message} supplied by the given {@link Supplier} at warning level.
*
* @param message {@link Supplier} containing the {@link String message} and arguments to log.
* @see org.apache.commons.logging.Log#isWarnEnabled()
* @see org.apache.commons.logging.Log#warn(Object)
* @see #getLog()
*/
protected void logWarning(Supplier<String> message) {
Optional.ofNullable(getLog())
.filter(Log::isWarnEnabled)
.ifPresent(log -> log.info(message.get()));
}
/**
* Logs the {@link String message} formatted with the array of {@link Object arguments} at error level.
*
* @param message {@link String} containing the message to log.
* @param args array of {@link Object arguments} used to format the {@code message}.
* @see #logError(Supplier)
*/
protected void logError(String message, Object... args) {
logError(() -> String.format(message, args));
}
/**
* Logs the {@link String message} supplied by the given {@link Supplier} at error level.
*
* @param message {@link Supplier} containing the {@link String message} and arguments to log.
* @see org.apache.commons.logging.Log#isErrorEnabled()
* @see org.apache.commons.logging.Log#error(Object)
* @see #getLog()
*/
protected void logError(Supplier<String> message) {
Optional.ofNullable(getLog())
.filter(Log::isWarnEnabled)
.ifPresent(log -> log.info(message.get()));
}
/**
* Registers the {@link AbstractBeanDefinition} with the {@link BeanDefinitionRegistry} using a generated bean name.
*
@@ -246,4 +437,297 @@ public abstract class AbstractAnnotationConfigSupport
return beanDefinition;
}
/* (non-Javadoc) */
protected List<String> arrayOfPropertyNamesFor(String propertyNamePrefix) {
return arrayOfPropertyNamesFor(propertyNamePrefix, null);
}
/* (non-Javadoc) */
protected List<String> arrayOfPropertyNamesFor(String propertyNamePrefix, String propertyNameSuffix) {
List<String> propertyNames = new ArrayList<>();
boolean found = true;
for (int index = 0; (found && index < Integer.MAX_VALUE); index++) {
String propertyName = asArrayProperty(propertyNamePrefix, index, propertyNameSuffix);
found = environment().containsProperty(propertyName);
if (found) {
propertyNames.add(propertyName);
}
}
return propertyNames;
}
/* (non-Javadoc) */
protected String asArrayProperty(String propertyNamePrefix, int index, String propertyNameSuffix) {
return String.format("%1$s[%2$d]%3$s", propertyNamePrefix, index,
Optional.ofNullable(propertyNamePrefix).filter(StringUtils::hasText).map("."::concat).orElse(""));
}
/* (non-Javadoc) */
protected String cacheProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("cache."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String cacheClientProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("cache.client."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String cachePeerProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("cache.peer."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String cacheServerProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("cache.server."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String namedCacheServerProperty(String name, String propertyNameSuffix) {
return String.format("%1$s%2$s.%3$s", propertyName("cache.server."), name, propertyNameSuffix);
}
/* (non-Javadoc) */
protected String diskStoreProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("disk.store."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String namedDiskStoreProperty(String name, String propertyNameSuffix) {
return String.format("%1$s%2$s.%3$s", propertyName("disk.store."), name, propertyNameSuffix);
}
/* (non-Javadoc) */
protected String locatorProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("locator."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String loggingProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("logging."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String managerProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("manager."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String pdxProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("pdx."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String poolProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("pool."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String namedPoolProperty(String name, String propertyNameSuffix) {
return String.format("%1$s%2$s.%3$s", propertyName("pool."), name, propertyNameSuffix);
}
/* (non-Javadoc) */
protected String securityProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("security."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String sslProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", securityProperty("ssl."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String componentSslProperty(String component, String propertyNameSuffix) {
return String.format("%1$s%2$s.%3$s", securityProperty("ssl."),
component, propertyNameSuffix);
}
/* (non-Javadoc) */
protected String statsProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("stats."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String serviceProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", propertyName("service."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String redisServiceProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", serviceProperty("redis."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String memcachedServiceProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", serviceProperty("memcached."), propertyNameSuffix);
}
/* (non-Javadoc) */
protected String httpServiceProperty(String propertyNameSuffix) {
return String.format("%1$s%2$s", serviceProperty("http."), propertyNameSuffix);
}
/**
* Returns the fully-qualified {@link String property name}.
*
* The fully qualified {@link String property name} consists of the {@link String property name}
* concatenated with the {@code propertyNameSuffix}.
*
* @param propertyNameSuffix {@link String} containing the property name suffix
* concatenated with the {@link String base property name}.
* @return the fully-qualified {@link String property name}.
* @see java.lang.String
*/
protected String propertyName(String propertyNameSuffix) {
return String.format("%1$s%2$s", SPRING_DATA_GEMFIRE_PROPERTY_PREFIX, propertyNameSuffix);
}
/**
* Resolves the value for the given property identified by {@link String name} from the Spring {@link Environment}
* as an instance of the specified {@link Class type}.
*
* @param <T> {@link Class} type of the {@code propertyName property's} assigned value.
* @param propertyName {@link String} containing the name of the required property to resolve.
* @param type {@link Class} type of the property's assigned value.
* @return the assigned value of the {@link String named} property.
* @throws IllegalArgumentException if the property has not been assigned a value.
* For {@link String} values, this also means the value cannot be {@link String#isEmpty() empty}.
* For non-{@link String} values, this means the value must not be {@literal null}.
* @see #resolveProperty(String, Class, Object)
*/
protected <T> T requireProperty(String propertyName, Class<T> type) {
return Optional.of(propertyName)
.map(it -> resolveProperty(propertyName, type, null))
.filter(Objects::nonNull)
.filter(value -> !(value instanceof String) || StringUtils.hasText((String) value))
.orElseThrow(() -> newIllegalArgumentException("Property [%s] is required", propertyName));
}
/**
* Attempts to resolve the property with the given {@link String name} from the Spring {@link Environment}
* as a {@link Boolean}.
*
* @param propertyName {@link String name} of the property to resolve.
* @param defaultValue default value to return if the property is not defined or not set.
* @return the value of the property identified by {@link String name} or default value if the property
* is not defined or not set.
* @see #resolveProperty(String, Class, Object)
*/
protected Boolean resolveProperty(String propertyName, Boolean defaultValue) {
return resolveProperty(propertyName, Boolean.class, defaultValue);
}
/**
* Attempts to resolve the property with the given {@link String name} from the Spring {@link Environment}
* as an {@link Double}.
*
* @param propertyName {@link String name} of the property to resolve.
* @param defaultValue default value to return if the property is not defined or not set.
* @return the value of the property identified by {@link String name} or default value if the property
* is not defined or not set.
* @see #resolveProperty(String, Class, Object)
*/
protected Double resolveProperty(String propertyName, Double defaultValue) {
return resolveProperty(propertyName, Double.class, defaultValue);
}
/**
* Attempts to resolve the property with the given {@link String name} from the Spring {@link Environment}
* as an {@link Float}.
*
* @param propertyName {@link String name} of the property to resolve.
* @param defaultValue default value to return if the property is not defined or not set.
* @return the value of the property identified by {@link String name} or default value if the property
* is not defined or not set.
* @see #resolveProperty(String, Class, Object)
*/
protected Float resolveProperty(String propertyName, Float defaultValue) {
return resolveProperty(propertyName, Float.class, defaultValue);
}
/**
* Attempts to resolve the property with the given {@link String name} from the Spring {@link Environment}
* as an {@link Integer}.
*
* @param propertyName {@link String name} of the property to resolve.
* @param defaultValue default value to return if the property is not defined or not set.
* @return the value of the property identified by {@link String name} or default value if the property
* is not defined or not set.
* @see #resolveProperty(String, Class, Object)
*/
protected Integer resolveProperty(String propertyName, Integer defaultValue) {
return resolveProperty(propertyName, Integer.class, defaultValue);
}
/**
* Attempts to resolve the property with the given {@link String name} from the Spring {@link Environment}
* as a {@link Long}.
*
* @param propertyName {@link String name} of the property to resolve.
* @param defaultValue default value to return if the property is not defined or not set.
* @return the value of the property identified by {@link String name} or default value if the property
* is not defined or not set.
* @see #resolveProperty(String, Class, Object)
*/
protected Long resolveProperty(String propertyName, Long defaultValue) {
return resolveProperty(propertyName, Long.class, defaultValue);
}
/**
* Attempts to resolve the property with the given {@link String name} from the Spring {@link Environment}
* as a {@link String}.
*
* @param propertyName {@link String name} of the property to resolve.
* @param defaultValue default value to return if the property is not defined or not set.
* @return the value of the property identified by {@link String name} or default value if the property
* is not defined or not set.
* @see #resolveProperty(String, Class, Object)
*/
protected String resolveProperty(String propertyName, String defaultValue) {
return resolveProperty(propertyName, String.class, defaultValue);
}
/**
* Attempts to resolve the property with the given {@link String name} from the Spring {@link Environment}.
*
* @param <T> {@link Class} type of the property value.
* @param propertyName {@link String name} of the property to resolve.
* @param targetType {@link Class} type of the property's value.
* @return the value of the property identified by {@link String name} or {@literal null} if the property
* is not defined or not set.
* @see #resolveProperty(String, Class, Object)
*/
protected <T> T resolveProperty(String propertyName, Class<T> targetType) {
return resolveProperty(propertyName, targetType, null);
}
/**
* Attempts to resolve the property with the given {@link String name} from the Spring {@link Environment}.
*
* @param <T> {@link Class} type of the property value.
* @param propertyName {@link String name} of the property to resolve.
* @param targetType {@link Class} type of the property's value.
* @param defaultValue default value to return if the property is not defined or not set.
* @return the value of the property identified by {@link String name} or default value if the property
* is not defined or not set.
* @see #environment()
*/
protected <T> T resolveProperty(String propertyName, Class<T> targetType, T defaultValue) {
return Optional.ofNullable(environment())
.filter(environment -> environment.containsProperty(propertyName))
.map(environment -> environment.getProperty(environment.resolveRequiredPlaceholders(propertyName),
targetType, defaultValue))
.orElse(defaultValue);
}
}

View File

@@ -64,6 +64,7 @@ public class CacheServerFactoryBean extends AbstractFactoryBeanSupport<CacheServ
private boolean autoStartup = true;
private boolean notifyBySubscription = CacheServer.DEFAULT_NOTIFY_BY_SUBSCRIPTION;
private boolean tcpNoDelay = CacheServer.DEFAULT_TCP_NO_DELAY;
private int maxConnections = CacheServer.DEFAULT_MAX_CONNECTIONS;
private int maxMessageCount = CacheServer.DEFAULT_MAXIMUM_MESSAGE_COUNT;
@@ -183,6 +184,7 @@ public class CacheServerFactoryBean extends AbstractFactoryBeanSupport<CacheServ
cacheServer.setNotifyBySubscription(this.notifyBySubscription);
cacheServer.setPort(this.port);
cacheServer.setSocketBufferSize(this.socketBufferSize);
cacheServer.setTcpNoDelay(this.tcpNoDelay);
nullSafeCollection(this.listeners).forEach(cacheServer::registerInterestRegistrationListener);
@@ -415,4 +417,9 @@ public class CacheServerFactoryBean extends AbstractFactoryBeanSupport<CacheServ
public void setSubscriptionEvictionPolicy(SubscriptionEvictionPolicy evictionPolicy) {
this.subscriptionEvictionPolicy = evictionPolicy;
}
/* (non-Javadoc) */
public void setTcpNoDelay(boolean tcpNoDelay) {
this.tcpNoDelay = tcpNoDelay;
}
}

View File

@@ -33,6 +33,8 @@ import org.springframework.beans.factory.FactoryBean;
* encapsulating operations common to SDG's {@link FactoryBean} implementations.
*
* @author John Blum
* @see org.apache.commons.logging.Log
* @see org.apache.commons.logging.LogFactory
* @see org.springframework.beans.factory.BeanClassLoaderAware
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.beans.factory.BeanFactoryAware
@@ -40,8 +42,9 @@ import org.springframework.beans.factory.FactoryBean;
* @see org.springframework.beans.factory.FactoryBean
* @since 1.0.0
*/
public abstract class AbstractFactoryBeanSupport<T> implements FactoryBean<T>,
BeanClassLoaderAware, BeanFactoryAware, BeanNameAware {
@SuppressWarnings("unused")
public abstract class AbstractFactoryBeanSupport<T>
implements FactoryBean<T>, BeanClassLoaderAware, BeanFactoryAware, BeanNameAware {
protected static final boolean DEFAULT_SINGLETON = true;
@@ -49,10 +52,19 @@ public abstract class AbstractFactoryBeanSupport<T> implements FactoryBean<T>,
private BeanFactory beanFactory;
private final Log log = newLog();
private final Log log;
private String beanName;
/**
* Constructs a new instance of {@link AbstractFactoryBeanSupport} and initialized the logger.
*
* @see #newLog()
*/
protected AbstractFactoryBeanSupport() {
this.log = newLog();
}
/**
* Constructs a new instance of {@link Log} to log statements printed by Spring Data GemFire/Geode.
*

View File

@@ -54,7 +54,7 @@ import org.springframework.data.gemfire.support.ConnectionEndpointList;
import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport;
import org.springframework.data.gemfire.util.PropertiesBuilder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import lombok.Data;
import lombok.NonNull;
@@ -75,11 +75,15 @@ import lombok.RequiredArgsConstructor;
* with the data of interest are targeted.
*
* @author John Blum
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.springframework.data.gemfire.GemfireTemplate
* @see org.springframework.test.context.ContextConfiguration
* @see org.springframework.test.context.junit4.SpringRunner
* @see <a href="https://jira.spring.io/browse/SGF-555">Repository queries on client Regions associated with a Pool configured with a specified server group can lead to a RegionNotFoundException.</a>
* @since 1.9.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration(classes =
GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationTests.GemFireClientCacheConfiguration.class)
@SuppressWarnings("unused")
@@ -147,6 +151,7 @@ public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationT
static class GemFireClientCacheConfiguration {
Properties gemfireProperties() {
return PropertiesBuilder.create()
.setProperty("name", applicationName())
.setProperty("log-level", logLevel())
@@ -163,6 +168,7 @@ public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationT
@Bean
ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean();
gemfireCache.setClose(true);
@@ -174,6 +180,7 @@ public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationT
@Bean(name = "ServerOnePool")
PoolFactoryBean serverOnePool() {
PoolFactoryBean serverOnePool = new PoolFactoryBean();
serverOnePool.setMaxConnections(2);
@@ -188,6 +195,7 @@ public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationT
@Bean(name = "ServerTwoPool")
PoolFactoryBean serverTwoPool() {
PoolFactoryBean serverOnePool = new PoolFactoryBean();
serverOnePool.setMaxConnections(2);
@@ -248,6 +256,7 @@ public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationT
static abstract class AbstractGemFireCacheServerConfiguration {
Properties gemfireProperties() {
return PropertiesBuilder.create()
.setProperty("name", applicationName())
.setProperty("mcast-port", "0")
@@ -275,6 +284,7 @@ public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationT
@Bean
CacheFactoryBean gemfireCache() {
CacheFactoryBean gemfireCache = new CacheFactoryBean();
gemfireCache.setClose(true);
@@ -284,11 +294,12 @@ public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationT
}
@Bean
CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache) {
CacheServerFactoryBean gemfireCacheServer(GemFireCache gemfireCache) {
CacheServerFactoryBean gemfireCacheServer = new CacheServerFactoryBean();
gemfireCacheServer.setAutoStartup(true);
gemfireCacheServer.setCache(gemfireCache);
gemfireCacheServer.setCache((Cache) gemfireCache);
gemfireCacheServer.setMaxTimeBetweenPings(Long.valueOf(TimeUnit.SECONDS.toMillis(60)).intValue());
gemfireCacheServer.setPort(cacheServerPort());
@@ -336,7 +347,8 @@ public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationT
}
@Bean(name = "Cats")
LocalRegionFactoryBean catsRegion(Cache gemfireCache) {
LocalRegionFactoryBean catsRegion(GemFireCache gemfireCache) {
LocalRegionFactoryBean catsRegion = new LocalRegionFactoryBean();
catsRegion.setCache(gemfireCache);
@@ -381,7 +393,8 @@ public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationT
}
@Bean(name = "Dogs")
LocalRegionFactoryBean<String, Dog> dogsRegion(Cache gemfireCache) {
LocalRegionFactoryBean<String, Dog> dogsRegion(GemFireCache gemfireCache) {
LocalRegionFactoryBean<String, Dog> dogsRegion = new LocalRegionFactoryBean<String, Dog>();
dogsRegion.setCache(gemfireCache);

View File

@@ -76,20 +76,24 @@ public class AbstractCacheConfigurationUnitTests {
}
@SuppressWarnings("unchecked")
protected <T> T invokeMethod(Object obj, String methodName) throws Exception {
private <T> T invokeMethod(Object obj, String methodName) throws Exception {
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.setTargetObject(obj);
methodInvoker.setTargetMethod(methodName);
methodInvoker.prepare();
return (T) methodInvoker.invoke();
}
@Test
public void configurePdxWhenEnablePdxIsConfigured() {
AnnotationMetadata mockAnnotationMetadata = mock(AnnotationMetadata.class);
PdxSerializer mockPdxSerializer = mock(PdxSerializer.class);
Map<String, Object> annotationAttributes = new HashMap<String, Object>(5);
Map<String, Object> annotationAttributes = new HashMap<>(5);
annotationAttributes.put("diskStoreName", "BlockDiskStore");
annotationAttributes.put("ignoreUnreadFields", Boolean.FALSE);
@@ -98,19 +102,18 @@ public class AbstractCacheConfigurationUnitTests {
annotationAttributes.put("serializerBeanName", "MockPdxSerializer");
when(mockAnnotationMetadata.hasAnnotation(eq(EnablePdx.class.getName()))).thenReturn(true);
when(mockAnnotationMetadata.getAnnotationAttributes(eq(EnablePdx.class.getName())))
.thenReturn(annotationAttributes);
when(mockAnnotationMetadata.getAnnotationAttributes(eq(EnablePdx.class.getName()))).thenReturn(annotationAttributes);
when(mockBeanFactory.containsBean(eq("MockPdxSerializer"))).thenReturn(true);
when(mockBeanFactory.getBean(eq("MockPdxSerializer"), eq(PdxSerializer.class))).thenReturn(mockPdxSerializer);
cacheConfiguration.setBeanFactory(mockBeanFactory);
cacheConfiguration.configurePdx(mockAnnotationMetadata);
assertThat(cacheConfiguration.pdxDiskStoreName()).isEqualTo("BlockDiskStore");
assertThat(cacheConfiguration.pdxIgnoreUnreadFields()).isFalse();
assertThat(cacheConfiguration.pdxPersistent()).isTrue();
assertThat(cacheConfiguration.pdxReadSerialized()).isTrue();
assertThat(cacheConfiguration.pdxSerializer()).isEqualTo(mockPdxSerializer);
assertThat(cacheConfiguration.getPdxDiskStoreName()).isEqualTo("BlockDiskStore");
assertThat(cacheConfiguration.getPdxIgnoreUnreadFields()).isFalse();
assertThat(cacheConfiguration.getPdxPersistent()).isTrue();
assertThat(cacheConfiguration.getPdxReadSerialized()).isTrue();
assertThat(cacheConfiguration.getPdxSerializer()).isEqualTo(mockPdxSerializer);
verify(mockAnnotationMetadata, times(1)).hasAnnotation(eq(EnablePdx.class.getName()));
verify(mockAnnotationMetadata, times(1)).getAnnotationAttributes(eq(EnablePdx.class.getName()));
@@ -120,17 +123,18 @@ public class AbstractCacheConfigurationUnitTests {
@Test
public void configurePdxWhenEnablePdxIsNotConfigured() {
AnnotationMetadata mockAnnotationMetadata = mock(AnnotationMetadata.class);
when(mockAnnotationMetadata.hasAnnotation(anyString())).thenReturn(false);
cacheConfiguration.configurePdx(mockAnnotationMetadata);
assertThat(cacheConfiguration.pdxDiskStoreName()).isNull();
assertThat(cacheConfiguration.pdxIgnoreUnreadFields()).isNull();
assertThat(cacheConfiguration.pdxPersistent()).isNull();
assertThat(cacheConfiguration.pdxReadSerialized()).isNull();
assertThat(cacheConfiguration.pdxSerializer()).isNull();
assertThat(cacheConfiguration.getPdxDiskStoreName()).isNull();
assertThat(cacheConfiguration.getPdxIgnoreUnreadFields()).isNull();
assertThat(cacheConfiguration.getPdxPersistent()).isNull();
assertThat(cacheConfiguration.getPdxReadSerialized()).isNull();
assertThat(cacheConfiguration.getPdxSerializer()).isNull();
verify(mockAnnotationMetadata, times(1)).hasAnnotation(eq(EnablePdx.class.getName()));
verifyNoMoreInteractions(mockAnnotationMetadata);
@@ -138,6 +142,7 @@ public class AbstractCacheConfigurationUnitTests {
@Test
public void resolvePdxSerializerUsesPdxSerializerBean() {
PdxSerializer mockPdxSerializer = mock(PdxSerializer.class);
when(mockBeanFactory.containsBean(anyString())).thenReturn(true);
@@ -155,6 +160,7 @@ public class AbstractCacheConfigurationUnitTests {
@Test
public void resolvePdxSerializerUsesConfiguredPdxSerializer() {
PdxSerializer mockPdxSerializer = mock(PdxSerializer.class);
when(mockBeanFactory.containsBean(anyString())).thenReturn(false);
@@ -173,6 +179,7 @@ public class AbstractCacheConfigurationUnitTests {
@Test
public void resolvePdxSerializerCallsNewMappingPdxSerializer() {
AbstractCacheConfiguration cacheConfigurationSpy = spy(this.cacheConfiguration);
MappingPdxSerializer mockPdxSerializer = mock(MappingPdxSerializer.class);
@@ -192,6 +199,7 @@ public class AbstractCacheConfigurationUnitTests {
@Test
public void newPdxSerializerUsesConfiguredConversionServiceAndMappingContext() throws Exception {
ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class);
ConversionService mockConversionService = mock(ConversionService.class);
GemfireMappingContext mockMappingContext = mock(GemfireMappingContext.class);
@@ -207,13 +215,14 @@ public class AbstractCacheConfigurationUnitTests {
assertThat((Object) invokeMethod(pdxSerializer, "getConversionService")).isEqualTo(mockConversionService);
assertThat((Object) invokeMethod(pdxSerializer, "getMappingContext")).isEqualTo(mockMappingContext);
verify(mockBeanFactory, times(1)).getConversionService();
verify(mockBeanFactory, times(2)).getConversionService();
verifyZeroInteractions(mockConversionService);
verifyZeroInteractions(mockMappingContext);
}
@Test
public void newPdxSerializerDefaultsConversionServiceAndMappingContextWhenNotConfigured() throws Exception {
cacheConfiguration.setBeanFactory(mockBeanFactory);
MappingPdxSerializer pdxSerializer = cacheConfiguration.newPdxSerializer();

View File

@@ -0,0 +1,132 @@
/*
* 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.config.annotation;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Optional;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.server.CacheServer;
import org.apache.geode.cache.server.ClientSubscriptionConfig;
import org.junit.After;
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.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.data.gemfire.server.SubscriptionEvictionPolicy;
import org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport;
import org.springframework.mock.env.MockPropertySource;
/**
* The CacheServerPropertiesIntegrationTests class...
*
* @author John Blum
* @since 1.0.0
*/
public class CacheServerPropertiesIntegrationTests {
private ConfigurableApplicationContext applicationContext;
@After
public void tearDown() {
Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close);
}
private ConfigurableApplicationContext newApplicationContext(PropertySource<?> testPropertySource,
Class<?>... annotatedClasses) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();
propertySources.addFirst(testPropertySource);
applicationContext.registerShutdownHook();
applicationContext.register(annotatedClasses);
applicationContext.refresh();
return applicationContext;
}
@Test
public void cacheServerConfigurationIsCorrect() {
MockPropertySource testPropertySource = new MockPropertySource()
.withProperty("gemfire.cache.server.port", "12480")
.withProperty("spring.data.gemfire.cache.server.bind-address", "10.120.12.1")
.withProperty("spring.data.gemfire.cache.server.max-connections", 500)
.withProperty("spring.data.gemfire.cache.server.max-time-between-pings", 30000)
.withProperty("spring.data.gemfire.cache.server.TestCacheServer.max-time-between-pings", 15000)
.withProperty("spring.data.gemfire.cache.server.NonExistingCacheServer.max-time-between-pings", 5000)
.withProperty("spring.data.gemfire.cache.server.TestCacheServer.subscription-capacity", 200)
.withProperty("spring.data.gemfire.cache.server.port", "${gemfire.cache.server.port:12345}")
.withProperty("spring.data.gemfire.cache.server.TestCacheServer.subscription-eviction-policy", "MEM");
this.applicationContext = newApplicationContext(testPropertySource, TestCacheServerConfiguration.class);
assertThat(this.applicationContext).isNotNull();
assertThat(this.applicationContext.containsBean("TestCacheServer")).isTrue();
CacheServer testCacheServer = this.applicationContext.getBean("TestCacheServer", CacheServer.class);
assertThat(testCacheServer).isNotNull();
assertThat(testCacheServer.getBindAddress()).isEqualTo("10.120.12.1");
assertThat(testCacheServer.getHostnameForClients()).isEqualTo("skullbox");
assertThat(testCacheServer.getLoadPollInterval()).isEqualTo(CacheServer.DEFAULT_LOAD_POLL_INTERVAL);
assertThat(testCacheServer.getMaxConnections()).isEqualTo(1200);
assertThat(testCacheServer.getMaximumMessageCount()).isEqualTo(400000);
assertThat(testCacheServer.getMaxThreads()).isEqualTo(8);
assertThat(testCacheServer.getMessageTimeToLive()).isEqualTo(600);
assertThat(testCacheServer.getPort()).isEqualTo(12480);
assertThat(testCacheServer.getSocketBufferSize()).isEqualTo(CacheServer.DEFAULT_SOCKET_BUFFER_SIZE);
assertThat(testCacheServer.getTcpNoDelay()).isEqualTo(CacheServer.DEFAULT_TCP_NO_DELAY);
ClientSubscriptionConfig testClientSubscriptionConfig = testCacheServer.getClientSubscriptionConfig();
assertThat(testClientSubscriptionConfig).isNotNull();
assertThat(testClientSubscriptionConfig.getCapacity()).isEqualTo(200);
assertThat(testClientSubscriptionConfig.getDiskStoreName()).isEmpty();
assertThat(testClientSubscriptionConfig.getEvictionPolicy()).isEqualTo("mem");
}
// TODO add more tests!
@Configuration
@EnableCacheServer(name = "TestCacheServer", bindAddress = "192.16.0.22", hostnameForClients = "skullbox",
maxConnections = 100, maxThreads = 8, messageTimeToLive = 300, port = 11235, subscriptionCapacity = 100,
subscriptionEvictionPolicy = SubscriptionEvictionPolicy.ENTRY)
static class TestCacheServerConfiguration {
@Bean("gemfireCache")
GemFireCache mockGemFireCache() {
return MockGemFireObjectsSupport.mockPeerCache();
}
@Bean
CacheServerConfigurer testCacheServerConfigurer() {
return (beanName, beanFactory) -> {
beanFactory.setMaxConnections(1200);
beanFactory.setMaxMessageCount(400000);
beanFactory.setMessageTimeToLive(600);
};
}
}
}

View File

@@ -0,0 +1,162 @@
/*
* 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.config.annotation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import java.util.Optional;
import org.apache.geode.cache.client.ClientCache;
import org.apache.geode.cache.client.Pool;
import org.apache.geode.cache.client.PoolFactory;
import org.apache.geode.cache.control.ResourceManager;
import org.apache.geode.pdx.PdxSerializer;
import org.junit.After;
import org.junit.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMocking;
import org.springframework.mock.env.MockPropertySource;
/**
* The ClientCachePropertiesIntegrationTests class...
*
* @author John Blum
* @since 1.0.0
*/
public class ClientCachePropertiesIntegrationTests {
private ConfigurableApplicationContext applicationContext;
@After
public void tearDown() {
Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close);
}
private ConfigurableApplicationContext newApplicationContext(PropertySource<?> testPropertySource,
Class<?>... annotatedClasses) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();
propertySources.addFirst(testPropertySource);
applicationContext.registerShutdownHook();
applicationContext.register(annotatedClasses);
applicationContext.refresh();
return applicationContext;
}
@Test
public void clientCacheConfiguration() {
MockPropertySource testPropertySource = new MockPropertySource()
.withProperty("spring.data.gemfire.cache.critical-heap-percentage", 90.0f)
.withProperty("spring.data.gemfire.cache.eviction-heap-percentage", 85.0f)
.withProperty("spring.data.gemfire.pdx.ignore-unread-fields", false)
.withProperty("spring.data.gemfire.pdx.persistent", true)
.withProperty("spring.data.gemfire.pool.free-connection-timeout", 20000L)
.withProperty("spring.data.gemfire.pool.max-connections", 250)
.withProperty("spring.data.gemfire.pool.ping-interval", 5000L)
.withProperty("spring.data.gemfire.pool.pr-single-hop-enabled", false)
.withProperty("spring.data.gemfire.pool.default.read-timeout", 5000L)
.withProperty("spring.data.gemfire.pool.read-timeout", 20000L)
.withProperty("spring.data.gemfire.pool.retry-attempts", 2)
.withProperty("spring.data.gemfire.pool.server-group", "testGroup")
.withProperty("spring.data.gemfire.pool.default.subscription-redundancy", 2);
this.applicationContext = newApplicationContext(testPropertySource, TestClientCacheConfiguration.class);
assertThat(this.applicationContext).isNotNull();
assertThat(this.applicationContext.containsBean("gemfireCache")).isTrue();
assertThat(this.applicationContext.containsBean("mockPdxSerializer")).isTrue();
ClientCache testClientCache = this.applicationContext.getBean("gemfireCache", ClientCache.class);
PdxSerializer mockPdxSerializer = this.applicationContext.getBean("mockPdxSerializer", PdxSerializer.class);
assertThat(mockPdxSerializer).isNotNull();
assertThat(testClientCache).isNotNull();
assertThat(testClientCache.getCopyOnRead()).isTrue();
assertThat(testClientCache.getPdxDiskStore()).isNull();
assertThat(testClientCache.getPdxIgnoreUnreadFields()).isFalse();
assertThat(testClientCache.getPdxPersistent()).isTrue();
assertThat(testClientCache.getPdxReadSerialized()).isFalse();
assertThat(testClientCache.getPdxSerializer()).isSameAs(mockPdxSerializer);
Pool defaultPool = testClientCache.getDefaultPool();
assertThat(defaultPool).isNotNull();
assertThat(defaultPool.getFreeConnectionTimeout()).isEqualTo(20000);
assertThat(defaultPool.getIdleTimeout()).isEqualTo(15000L);
assertThat(defaultPool.getLoadConditioningInterval()).isEqualTo(180000);
assertThat(defaultPool.getMaxConnections()).isEqualTo(250);
assertThat(defaultPool.getMinConnections()).isEqualTo(50);
assertThat(defaultPool.getMultiuserAuthentication()).isFalse();
assertThat(defaultPool.getName()).isEqualTo("DEFAULT");
assertThat(defaultPool.getPingInterval()).isEqualTo(5000L);
assertThat(defaultPool.getPRSingleHopEnabled()).isFalse();
assertThat(defaultPool.getReadTimeout()).isEqualTo(5000);
assertThat(defaultPool.getRetryAttempts()).isEqualTo(2);
assertThat(defaultPool.getServerGroup()).isEqualTo("testGroup");
assertThat(defaultPool.getSocketBufferSize()).isEqualTo(PoolFactory.DEFAULT_SOCKET_BUFFER_SIZE);
assertThat(defaultPool.getStatisticInterval()).isEqualTo(500);
assertThat(defaultPool.getSubscriptionAckInterval()).isEqualTo(PoolFactory.DEFAULT_SUBSCRIPTION_ACK_INTERVAL);
assertThat(defaultPool.getSubscriptionEnabled()).isTrue();
assertThat(defaultPool.getSubscriptionMessageTrackingTimeout()).isEqualTo(PoolFactory.DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT);
assertThat(defaultPool.getSubscriptionRedundancy()).isEqualTo(2);
ResourceManager resourceManager = testClientCache.getResourceManager();
assertThat(resourceManager).isNotNull();
assertThat(resourceManager.getCriticalHeapPercentage()).isEqualTo(90.0f);
assertThat(resourceManager.getEvictionHeapPercentage()).isEqualTo(90.0f);
}
// TODO add more tests!
@EnableGemFireMocking
@EnablePdx(ignoreUnreadFields = true, readSerialized = true, serializerBeanName = "mockPdxSerializer")
@ClientCacheApplication(name = "TestClientCache", copyOnRead = true,
criticalHeapPercentage = 95.0f, evictionHeapPercentage = 80.0f, idleTimeout = 15000L,
maxConnections = 100, minConnections = 10, pingInterval = 15000L, readTimeout = 15000, retryAttempts = 1,
subscriptionEnabled = true, subscriptionRedundancy = 1)
static class TestClientCacheConfiguration {
@Bean
ClientCacheConfigurer testClientCacheConfigurer() {
return (beanName, factoryBean) -> {
factoryBean.setEvictionHeapPercentage(90.0f);
factoryBean.setPdxReadSerialized(false);
factoryBean.setLoadConditioningInterval(180000);
factoryBean.setMinConnections(50);
factoryBean.setStatisticsInterval(500);
};
}
@Bean
PdxSerializer mockPdxSerializer() {
return mock(PdxSerializer.class);
}
}
}

View File

@@ -67,6 +67,7 @@ public class ClientServerCacheApplicationIntegrationTests extends ClientServerIn
@BeforeClass
public static void setupGemFireServer() throws Exception {
gemfireServerProcess = run(CacheServerApplicationConfiguration.class, String.format("-Dgemfire.name=%1$s",
asApplicationName(ClientServerCacheApplicationIntegrationTests.class)));
@@ -99,6 +100,7 @@ public class ClientServerCacheApplicationIntegrationTests extends ClientServerIn
@Bean("Echo")
public PartitionedRegionFactoryBean<String, String> echoRegion(Cache gemfireCache) {
PartitionedRegionFactoryBean<String, String> echoRegion =
new PartitionedRegionFactoryBean<String, String>();
@@ -111,6 +113,7 @@ public class ClientServerCacheApplicationIntegrationTests extends ClientServerIn
}
CacheLoader<String, String> echoCacheLoader() {
return new CacheLoader<String, String>() {
@Override
public String load(LoaderHelper<String, String> helper) throws CacheLoaderException {
@@ -129,6 +132,7 @@ public class ClientServerCacheApplicationIntegrationTests extends ClientServerIn
@Bean(name = "Echo")
ClientRegionFactoryBean<String, String> echoRegion(ClientCache gemfireCache) {
ClientRegionFactoryBean<String, String> echoRegion = new ClientRegionFactoryBean<String, String>();
echoRegion.setCache(gemfireCache);

View File

@@ -0,0 +1,121 @@
/*
* 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.config.annotation;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Optional;
import org.apache.geode.cache.DiskStore;
import org.apache.geode.cache.DiskStoreFactory;
import org.apache.geode.cache.GemFireCache;
import org.junit.After;
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.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport;
import org.springframework.mock.env.MockPropertySource;
/**
* The DiskStorePropertiesIntegrationTests class...
*
* @author John Blum
* @since 1.0.0
*/
public class DiskStorePropertiesIntegrationTests {
private ConfigurableApplicationContext applicationContext;
@After
public void tearDown() {
Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close);
}
private ConfigurableApplicationContext newApplicationContext(PropertySource<?> testPropertySource,
Class<?>... annotatedClasses) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();
propertySources.addFirst(testPropertySource);
applicationContext.registerShutdownHook();
applicationContext.register(annotatedClasses);
applicationContext.refresh();
return applicationContext;
}
@Test
public void diskStoreConfigurationIsCorrect() {
MockPropertySource testPropertySource = new MockPropertySource()
.withProperty("spring.data.gemfire.disk.store.compaction-threshold", 85)
.withProperty("spring.data.gemfire.disk.store.disk-usage-critical-percentage", 90.0f)
.withProperty("spring.data.gemfire.disk.store.disk-usage-warning-percentage", 80.0f)
.withProperty("spring.data.gemfire.disk.store.TestDiskStore.disk-usage-warning-percentage", 85.0f)
.withProperty("spring.data.gemfire.disk.store.time-interval", 500L)
.withProperty("spring.data.gemfire.disk.store.NonExistingDiskStore.time-interval", 30000L);
this.applicationContext = newApplicationContext(testPropertySource, TestDiskStoreConfiguration.class);
assertThat(this.applicationContext).isNotNull();
assertThat(this.applicationContext.containsBean("TestDiskStore")).isTrue();
DiskStore testDiskStore = this.applicationContext.getBean("TestDiskStore", DiskStore.class);
assertThat(testDiskStore).isNotNull();
assertThat(testDiskStore.getName()).isEqualTo("TestDiskStore");
assertThat(testDiskStore.getAllowForceCompaction()).isTrue();
assertThat(testDiskStore.getAutoCompact()).isTrue();
assertThat(testDiskStore.getCompactionThreshold()).isEqualTo(75);
assertThat(testDiskStore.getDiskUsageCriticalPercentage()).isEqualTo(90.0f);
assertThat(testDiskStore.getDiskUsageWarningPercentage()).isEqualTo(85.0f);
assertThat(testDiskStore.getMaxOplogSize()).isEqualTo(512L);
assertThat(testDiskStore.getQueueSize()).isEqualTo(DiskStoreFactory.DEFAULT_QUEUE_SIZE);
assertThat(testDiskStore.getTimeInterval()).isEqualTo(500L);
assertThat(testDiskStore.getWriteBufferSize()).isEqualTo(DiskStoreFactory.DEFAULT_WRITE_BUFFER_SIZE);
}
// TODO add more tests!
@Configuration
@EnableDiskStore(name = "TestDiskStore", allowForceCompaction = true, compactionThreshold = 65,
diskUsageCriticalPercentage = 95.0f, diskUsageWarningPercentage = 75.0f, maxOplogSize = 2048L)
@SuppressWarnings("unused")
static class TestDiskStoreConfiguration {
@Bean("gemfireCache")
GemFireCache mockGemFireCache() {
return MockGemFireObjectsSupport.mockGemFireCache();
}
@Bean
DiskStoreConfigurer testDiskStoreConfigurer() {
return (beanName, factoryBean) -> {
factoryBean.setCompactionThreshold(75);
//factoryBean.setDiskUsageWarningPercentage(95.0f);
factoryBean.setMaxOplogSize(512L);
};
}
}
}

View File

@@ -18,30 +18,19 @@
package org.springframework.data.gemfire.config.annotation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyFloat;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.File;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.DiskStore;
import org.apache.geode.cache.DiskStoreFactory;
import org.junit.After;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
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;
/**
* Unit tests for the {@link EnableDiskStore} and {@link EnableDiskStores} annotations as well as
@@ -49,7 +38,12 @@ import org.springframework.context.annotation.Configuration;
*
* @author John Blum
* @see org.junit.Test
* @see org.mockito.Mockito
* @see org.apache.geode.cache.DiskStore
* @see org.springframework.context.ConfigurableApplicationContext
* @see org.springframework.data.gemfire.config.annotation.EnableDiskStore
* @see org.springframework.data.gemfire.config.annotation.EnableDiskStores
* @see org.springframework.data.gemfire.config.annotation.DiskStoreConfiguration
* @see org.springframework.data.gemfire.config.annotation.DiskStoresConfiguration
* @since 1.9.0
*/
public class EnableDiskStoresConfigurationUnitTests {
@@ -60,13 +54,11 @@ public class EnableDiskStoresConfigurationUnitTests {
@After
public void tearDown() {
if (applicationContext != null) {
applicationContext.close();
}
Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close);
}
/* (non-Javadoc) */
protected void assertDiskStore(DiskStore diskStore, String name, boolean allowForceCompaction, boolean autoCompact,
private void assertDiskStore(DiskStore diskStore, String name, boolean allowForceCompaction, boolean autoCompact,
int compactionThreshold, float diskUsageCriticalPercentage, float diskUsageWarningPercentage,
long maxOplogSize, int queueSize, long timeInterval, int writeBufferSize) {
@@ -84,7 +76,8 @@ public class EnableDiskStoresConfigurationUnitTests {
}
/* (non-Javadoc) */
protected void assertDiskStoreDirectoryLocations(DiskStore diskStore, File... diskDirectories) {
private void assertDiskStoreDirectoryLocations(DiskStore diskStore, File... diskDirectories) {
assertThat(diskStore).isNotNull();
File[] diskStoreDirectories = diskStore.getDiskDirs();
@@ -100,7 +93,8 @@ public class EnableDiskStoresConfigurationUnitTests {
}
/* (non-Javadoc) */
protected void assertDiskStoreDirectorySizes(DiskStore diskStore, int... diskDirectorySizes) {
private void assertDiskStoreDirectorySizes(DiskStore diskStore, int... diskDirectorySizes) {
assertThat(diskStore).isNotNull();
int[] diskStoreDirectorySizes = diskStore.getDiskDirSizes();
@@ -116,22 +110,23 @@ public class EnableDiskStoresConfigurationUnitTests {
}
/* (non-Javadoc) */
protected File newFile(String location) {
return new File(location);
}
/* (non-Javadoc) */
protected ConfigurableApplicationContext newApplicationContext(Class<?>... annotatedClasses) {
private ConfigurableApplicationContext newApplicationContext(Class<?>... annotatedClasses) {
ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(annotatedClasses);
applicationContext.registerShutdownHook();
return applicationContext;
}
/* (non-Javadoc) */
private File newFile(String location) {
return new File(location);
}
@Test
public void enableSingleDiskStore() {
applicationContext = newApplicationContext(SingleDiskStoreConfiguration.class);
DiskStore testDiskStore = applicationContext.getBean("TestDiskStore", DiskStore.class);
this.applicationContext = newApplicationContext(SingleDiskStoreConfiguration.class);
DiskStore testDiskStore = this.applicationContext.getBean("TestDiskStore", DiskStore.class);
assertDiskStore(testDiskStore, "TestDiskStore", true, true, 75, 95.0f, 75.0f, 8192L, 100, 2000L, 65536);
assertDiskStoreDirectoryLocations(testDiskStore, newFile("/absolute/path/to/gemfire/disk/directory"),
@@ -140,14 +135,15 @@ public class EnableDiskStoresConfigurationUnitTests {
}
@Test
public void enablesMultipleDiskStores() {
applicationContext = newApplicationContext(MultipleDiskStoresConfiguration.class);
public void enableMultipleDiskStores() {
DiskStore testDiskStoreOne = applicationContext.getBean("TestDiskStoreOne", DiskStore.class);
this.applicationContext = newApplicationContext(MultipleDiskStoresConfiguration.class);
DiskStore testDiskStoreOne = this.applicationContext.getBean("TestDiskStoreOne", DiskStore.class);
assertDiskStore(testDiskStoreOne, "TestDiskStoreOne", false, true, 75, 99.0f, 90.0f, 2048L, 100, 1000L, 32768);
DiskStore testDiskStoreTwo = applicationContext.getBean("TestDiskStoreTwo", DiskStore.class);
DiskStore testDiskStoreTwo = this.applicationContext.getBean("TestDiskStoreTwo", DiskStore.class);
assertDiskStore(testDiskStoreTwo, "TestDiskStoreTwo", true, true, 85, 99.0f, 90.0f, 4096L, 0, 1000L, 32768);
}
@@ -169,121 +165,26 @@ public class EnableDiskStoresConfigurationUnitTests {
};
}
@Configuration
@SuppressWarnings("unused")
static class CacheConfiguration {
@Bean
Cache gemfireCache() {
Cache mockCache = mock(Cache.class);
when(mockCache.createDiskStoreFactory()).thenAnswer(new Answer<DiskStoreFactory>() {
@Override
public DiskStoreFactory answer(InvocationOnMock invocation) throws Throwable {
final DiskStoreFactory mockDiskStoreFactory =
mock(DiskStoreFactory.class, mockName("MockDiskStoreFactory"));
final AtomicReference<Boolean> allowForceCompaction = new AtomicReference<>(false);
final AtomicReference<Boolean> autoCompact = new AtomicReference<>(false);
final AtomicReference<Integer> compactionThreshold = new AtomicReference<>(50);
final AtomicReference<File[]> diskDirectories = new AtomicReference<>(new File[0]);
final AtomicReference<int[]> diskDirectorySizes = new AtomicReference<>(new int[0]);
final AtomicReference<Float> diskUsageCriticalPercentage = new AtomicReference<>(99.0f);
final AtomicReference<Float> diskUsageWarningPercentage = new AtomicReference<>(90.0f);
final AtomicReference<Long> maxOplogSize = new AtomicReference<>(1024L);
final AtomicReference<Integer> queueSize = new AtomicReference<>(0);
final AtomicReference<Long> timeInterval = new AtomicReference<>(1000L);
final AtomicReference<Integer> writeBufferSize = new AtomicReference<>(32768);
when(mockDiskStoreFactory.setAllowForceCompaction(anyBoolean())).thenAnswer(
newSetter(Boolean.TYPE, allowForceCompaction, mockDiskStoreFactory));
when(mockDiskStoreFactory.setAutoCompact(anyBoolean())).thenAnswer(
newSetter(Boolean.TYPE, autoCompact, mockDiskStoreFactory));
when(mockDiskStoreFactory.setCompactionThreshold(anyInt())).thenAnswer(
newSetter(Integer.TYPE, compactionThreshold, mockDiskStoreFactory));
when(mockDiskStoreFactory.setDiskDirsAndSizes(any(File[].class), any(int[].class))).thenAnswer(
new Answer<DiskStoreFactory>() {
@Override public DiskStoreFactory answer(InvocationOnMock invocation) throws Throwable {
File[] localDiskDirectories = invocation.getArgument(0);
int[] localDiskDirectorySizes = invocation.getArgument(1);
diskDirectories.set(localDiskDirectories);
diskDirectorySizes.set(localDiskDirectorySizes);
return mockDiskStoreFactory;
}
}
);
when(mockDiskStoreFactory.setDiskUsageCriticalPercentage(anyFloat())).thenAnswer(
newSetter(Float.TYPE, diskUsageCriticalPercentage, mockDiskStoreFactory));
when(mockDiskStoreFactory.setDiskUsageWarningPercentage(anyFloat())).thenAnswer(
newSetter(Float.TYPE, diskUsageWarningPercentage, mockDiskStoreFactory));
when(mockDiskStoreFactory.setMaxOplogSize(anyLong())).thenAnswer(
newSetter(Long.TYPE, maxOplogSize, mockDiskStoreFactory));
when(mockDiskStoreFactory.setQueueSize(anyInt())).thenAnswer(
newSetter(Integer.TYPE, queueSize, mockDiskStoreFactory));
when(mockDiskStoreFactory.setTimeInterval(anyLong())).thenAnswer(
newSetter(Long.TYPE, timeInterval, mockDiskStoreFactory));
when(mockDiskStoreFactory.setWriteBufferSize(anyInt())).thenAnswer(
newSetter(Integer.TYPE, writeBufferSize, mockDiskStoreFactory));
when(mockDiskStoreFactory.create(anyString())).thenAnswer(new Answer<DiskStore>() {
@Override
public DiskStore answer(InvocationOnMock invocation) throws Throwable {
String diskStoreName = invocation.getArgument(0);
DiskStore mockDiskStore = mock(DiskStore.class, diskStoreName);
when(mockDiskStore.getAllowForceCompaction()).thenAnswer(newGetter(allowForceCompaction));
when(mockDiskStore.getAutoCompact()).thenAnswer(newGetter(autoCompact));
when(mockDiskStore.getCompactionThreshold()).thenAnswer(newGetter(compactionThreshold));
when(mockDiskStore.getDiskDirs()).thenAnswer(newGetter(diskDirectories));
when(mockDiskStore.getDiskDirSizes()).thenAnswer(newGetter(diskDirectorySizes));
when(mockDiskStore.getDiskUsageCriticalPercentage()).thenAnswer(newGetter(diskUsageCriticalPercentage));
when(mockDiskStore.getDiskUsageWarningPercentage()).thenAnswer(newGetter(diskUsageWarningPercentage));
when(mockDiskStore.getMaxOplogSize()).thenAnswer(newGetter(maxOplogSize));
when(mockDiskStore.getName()).thenReturn(diskStoreName);
when(mockDiskStore.getQueueSize()).thenAnswer(newGetter(queueSize));
when(mockDiskStore.getTimeInterval()).thenAnswer(newGetter(timeInterval));
when(mockDiskStore.getWriteBufferSize()).thenAnswer(newGetter(writeBufferSize));
return mockDiskStore;
}
});
return mockDiskStoreFactory;
}
});
return mockCache;
}
}
@PeerCacheApplication
@EnableGemFireMocking
@EnableDiskStore(name = "TestDiskStore", allowForceCompaction = true, autoCompact = true, compactionThreshold = 75,
diskUsageCriticalPercentage = 95.0f, diskUsageWarningPercentage = 75.0f, maxOplogSize = 8192L, queueSize = 100,
timeInterval = 2000L, writeBufferSize = 65536, diskDirectories = {
@EnableDiskStore.DiskDirectory(location = "/absolute/path/to/gemfire/disk/directory", maxSize = 1024),
@EnableDiskStore.DiskDirectory(location = "relative/path/to/gemfire/disk/directory", maxSize = 4096)
})
static class SingleDiskStoreConfiguration extends CacheConfiguration {
static class SingleDiskStoreConfiguration {
}
@PeerCacheApplication
@EnableGemFireMocking
@EnableDiskStores(autoCompact = true, compactionThreshold = 75, maxOplogSize = 2048L, diskStores = {
@EnableDiskStore(name = "TestDiskStoreOne", queueSize = 100),
@EnableDiskStore(name = "TestDiskStoreTwo", allowForceCompaction = true,
compactionThreshold = 85, maxOplogSize = 4096)
})
static class MultipleDiskStoresConfiguration extends CacheConfiguration {
static class MultipleDiskStoresConfiguration {
}
}

View File

@@ -0,0 +1,129 @@
/*
* 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.config.annotation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import java.util.Optional;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.control.ResourceManager;
import org.apache.geode.pdx.PdxSerializer;
import org.junit.After;
import org.junit.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMocking;
import org.springframework.mock.env.MockPropertySource;
/**
* The PeerCachePropertiesIntegrationTests class...
*
* @author John Blum
* @since 1.0.0
*/
public class PeerCachePropertiesIntegrationTests {
private ConfigurableApplicationContext applicationContext;
@After
public void tearDown() {
Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close);
}
private ConfigurableApplicationContext newApplicationContext(PropertySource<?> testPropertySource,
Class<?>... annotatedClasses) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();
propertySources.addFirst(testPropertySource);
applicationContext.registerShutdownHook();
applicationContext.register(annotatedClasses);
applicationContext.refresh();
return applicationContext;
}
@Test
public void peerCacheConfiguration() {
MockPropertySource testPropertySource = new MockPropertySource()
.withProperty("spring.data.gemfire.cache.copy-on-read", true)
.withProperty("spring.data.gemfire.cache.critical-heap-percentage", 95.0f)
.withProperty("spring.data.gemfire.cache.eviction-heap-percentage", 85.0f)
.withProperty("spring.data.gemfire.cache.peer.lock-lease", 180)
.withProperty("spring.data.gemfire.cache.peer.lock-timeout", 30)
.withProperty("spring.data.gemfire.cache.peer.search-timeout", 120)
.withProperty("spring.data.gemfire.pdx.ignore-unread-fields", false)
.withProperty("spring.data.gemfire.pdx.persistent", true);
this.applicationContext = newApplicationContext(testPropertySource, TestPeerCacheConfiguration.class);
assertThat(this.applicationContext).isNotNull();
assertThat(this.applicationContext.containsBean("gemfireCache")).isTrue();
assertThat(this.applicationContext.containsBean("mockPdxSerializer")).isTrue();
Cache testPeerCache = this.applicationContext.getBean("gemfireCache", Cache.class);
PdxSerializer mockPdxSerializer = this.applicationContext.getBean("mockPdxSerializer", PdxSerializer.class);
assertThat(testPeerCache).isNotNull();
assertThat(mockPdxSerializer).isNotNull();
assertThat(testPeerCache.getLockLease()).isEqualTo(180);
assertThat(testPeerCache.getLockTimeout()).isEqualTo(30);
assertThat(testPeerCache.getPdxDiskStore()).isNull();
assertThat(testPeerCache.getPdxIgnoreUnreadFields()).isFalse();
assertThat(testPeerCache.getPdxPersistent()).isTrue();
assertThat(testPeerCache.getPdxReadSerialized()).isTrue();
assertThat(testPeerCache.getPdxSerializer()).isSameAs(mockPdxSerializer);
assertThat(testPeerCache.getSearchTimeout()).isEqualTo(60);
ResourceManager resourceManager = testPeerCache.getResourceManager();
assertThat(resourceManager).isNotNull();
assertThat(resourceManager.getCriticalHeapPercentage()).isEqualTo(95.0f);
assertThat(resourceManager.getEvictionHeapPercentage()).isEqualTo(85.0f);
}
//TODO add more tests
@EnableGemFireMocking
@EnablePdx(ignoreUnreadFields = true, readSerialized = true, serializerBeanName = "mockPdxSerializer")
@PeerCacheApplication(name = "TestPeerCache", criticalHeapPercentage = 90.0f, evictionHeapPercentage = 75.0f,
lockLease = 300, lockTimeout = 120)
static class TestPeerCacheConfiguration {
@Bean
PeerCacheConfigurer testPeerCacheConfigurer() {
return (beanName, beanFactory) -> {
beanFactory.setSearchTimeout(60);
};
}
@Bean
PdxSerializer mockPdxSerializer() {
return mock(PdxSerializer.class);
}
}
}

View File

@@ -0,0 +1,111 @@
/*
* 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.config.annotation.support;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
/**
* Unit tests for {@link AbstractAnnotationConfigSupport}.
*
* @author John Blum
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.mockito.Mock
* @see org.mockito.Mockito
* @see org.mockito.junit.MockitoJUnitRunner
* @see org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport
* @since 1.1.0
*/
@RunWith(MockitoJUnitRunner.class)
public class AbstractAnnotationConfigSupportTests {
@Mock
private AbstractAnnotationConfigSupport support;
@Test
public void requirePropertyWithNonStringValueIsSuccessful() {
when(support.requireProperty(anyString(), any())).thenCallRealMethod();
when(support.resolveProperty(anyString(), eq(Integer.class), eq(null))).thenReturn(1);
assertThat(support.requireProperty("key", Integer.class)).isEqualTo(1);
verify(support, times(1))
.resolveProperty(eq("key"), eq(Integer.class), eq(null));
}
@Test
public void requirePropertyWithStringValueIsSuccessful() {
when(support.requireProperty(anyString(), any())).thenCallRealMethod();
when(support.resolveProperty(anyString(), eq(String.class), eq(null))).thenReturn("test");
assertThat(support.requireProperty("key", String.class)).isEqualTo("test");
verify(support, times(1))
.resolveProperty(eq("key"), eq(String.class), eq(null));
}
@Test(expected = IllegalArgumentException.class)
public void requirePropertyWithEmptyStringThrowsIllegalArgumentException() {
when(support.requireProperty(anyString(), any())).thenCallRealMethod();
when(support.resolveProperty(anyString(), eq(String.class), eq(null))).thenReturn(" ");
try {
support.requireProperty("key", String.class);
}
catch (IllegalArgumentException expected) {
assertThat(expected).hasMessage("Property [key] is required");
assertThat(expected).hasNoCause();
throw expected;
}
finally {
verify(support, times(1))
.resolveProperty(eq("key"), eq(String.class), eq(null));
}
}
@Test(expected = IllegalArgumentException.class)
public void requirePropertyWithNullValueThrowsIllegalArgumentException() {
when(support.requireProperty(anyString(), any())).thenCallRealMethod();
when(support.resolveProperty(anyString(), any(), eq(null))).thenReturn(null);
try {
support.requireProperty("key", Integer.class);
}
catch (IllegalArgumentException expected) {
assertThat(expected).hasMessage("Property [key] is required");
assertThat(expected).hasNoCause();
throw expected;
}
finally {
verify(support, times(1))
.resolveProperty(eq("key"), eq(Integer.class), eq(null));
}
}
}

View File

@@ -30,19 +30,23 @@ import org.junit.runner.RunWith;
import org.springframework.context.annotation.Bean;
import org.springframework.data.gemfire.DiskStoreFactoryBean;
import org.springframework.data.gemfire.config.annotation.PeerCacheApplication;
import org.springframework.data.gemfire.test.support.FileSystemUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.FileSystemUtils;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Integration tests for {@link DiskStoreDirectoryBeanPostProcessor}.
*
* @author John Blum
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.springframework.data.gemfire.DiskStoreFactoryBean
* @see org.springframework.data.gemfire.config.support.DiskStoreDirectoryBeanPostProcessor
* @see org.springframework.test.context.ContextConfiguration
* @see org.springframework.test.context.junit4.SpringRunner
* @since 1.5.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@ContextConfiguration
public class DiskStoreDirectoryBeanPostProcessorIntegrationTests {
@@ -53,8 +57,8 @@ public class DiskStoreDirectoryBeanPostProcessorIntegrationTests {
@AfterClass
public static void testSuiteTearDown() {
assertThat(FileSystemUtils.deleteRecursively(new File("./gemfire"))).isTrue();
assertThat(FileSystemUtils.deleteRecursively(new File("./gfe"))).isTrue();
assertThat(FileSystemUtils.deleteRecursive(new File("./gemfire"))).isTrue();
assertThat(FileSystemUtils.deleteRecursive(new File("./gfe"))).isTrue();
}
@Test

View File

@@ -24,10 +24,6 @@ import org.springframework.data.gemfire.CacheFactoryBean;
*/
public class MockCacheFactoryBean extends CacheFactoryBean {
public MockCacheFactoryBean() {
this(null);
}
public MockCacheFactoryBean(CacheFactoryBean cacheFactoryBean) {
setUseBeanFactoryLocator(false);

View File

@@ -51,7 +51,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import org.apache.commons.lang.StringUtils;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.DiskStore;
@@ -77,7 +79,6 @@ import org.springframework.data.gemfire.test.support.FileSystemUtils;
* Mock GemFire Objects (e.g. {@link Cache}, {@link ClientCache}, {@link Region}, etc).
*
* @author John Blum
* @see org.mockito.Mockito
* @see org.apache.geode.cache.Cache
* @see org.apache.geode.cache.CacheFactory
* @see org.apache.geode.cache.DiskStore
@@ -89,10 +90,12 @@ import org.springframework.data.gemfire.test.support.FileSystemUtils;
* @see org.apache.geode.cache.server.CacheServer
* @see org.apache.geode.cache.server.ClientSubscriptionConfig
* @see org.apache.geode.distributed.DistributedSystem
* @see org.mockito.Mockito
* @see org.springframework.data.gemfire.test.mock.MockObjectsSupport
* @since 2.0.0
*/
@SuppressWarnings("unused")
public abstract class MockGemFireObjectsSupport {
public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
private static final Map<String, DiskStore> diskStores = new ConcurrentHashMap<>();
@@ -110,6 +113,11 @@ public abstract class MockGemFireObjectsSupport {
return (regionPath.lastIndexOf(Region.SEPARATOR) <= 0);
}
private static String toRegionPath(String regionPath) {
return (StringUtils.startsWith(regionPath, Region.SEPARATOR) ? regionPath
: String.format("%1$s%2$s", Region.SEPARATOR, regionPath));
}
/* (non-Javadoc) */
@SuppressWarnings("unchecked")
private static <T extends GemFireCache> T mockCacheApi(T mockGemFireCache) {
@@ -120,17 +128,12 @@ public abstract class MockGemFireObjectsSupport {
ResourceManager mockResourceManager = mockResourceManager();
doAnswer(invocation -> {
copyOnRead.set(invocation.getArgument(0));
return null;
}).when(mockGemFireCache).setCopyOnRead(anyBoolean());
doAnswer(newSetter(copyOnRead, null)).when(mockGemFireCache).setCopyOnRead(anyBoolean());
doAnswer(invocation -> {
regionAttributes.put(invocation.getArgument(0), invocation.getArgument(1));
return null;
}).when(mockGemFireCache).setRegionAttributes(anyString(), any(RegionAttributes.class));
doAnswer(newSetter(regionAttributes, null))
.when(mockGemFireCache).setRegionAttributes(anyString(), any(RegionAttributes.class));
when(mockGemFireCache.getCopyOnRead()).thenAnswer(invocation -> copyOnRead.get());
when(mockGemFireCache.getCopyOnRead()).thenAnswer(newGetter(copyOnRead));
when(mockGemFireCache.getDistributedSystem()).thenReturn(mockDistributedSystem);
@@ -155,14 +158,11 @@ public abstract class MockGemFireObjectsSupport {
/* (non-Javadoc) */
private static <T extends RegionService> T mockRegionServiceApi(T mockRegionService) {
AtomicBoolean close = new AtomicBoolean(false);
AtomicBoolean closed = new AtomicBoolean(false);
doAnswer(invocation -> {
close.set(true);
return null;
}).when(mockRegionService).close();
doAnswer(newSetter(closed, true, null)).when(mockRegionService).close();
when(mockRegionService.isClosed()).thenAnswer(invocation -> close.get());
when(mockRegionService.isClosed()).thenAnswer(newGetter(closed));
when(mockRegionService.getCancelCriterion()).thenThrow(newUnsupportedOperationException(NOT_SUPPORTED));
@@ -171,7 +171,7 @@ public abstract class MockGemFireObjectsSupport {
String regionPath = invocation.getArgument(0);
Optional.ofNullable(regionPath).map(String::trim).filter(it -> !it.isEmpty())
.map(it -> it.startsWith(Region.SEPARATOR) ? it : String.format("%1$s%2$s", Region.SEPARATOR, it))
.map(MockGemFireObjectsSupport::toRegionPath)
.orElseThrow(() -> newIllegalArgumentException("Region path [%s] is not valid", regionPath));
return regions.get(regionPath);
@@ -233,33 +233,18 @@ public abstract class MockGemFireObjectsSupport {
return mockCacheServer;
});
doAnswer(invocation -> {
lockLease.set(invocation.getArgument(0));
return null;
}).when(mockCache).setLockLease(anyInt());
doAnswer(invocation -> {
lockTimeout.set(invocation.getArgument(0));
return null;
}).when(mockCache).setLockTimeout(anyInt());
doAnswer(invocation -> {
messageSyncInterval.set(invocation.getArgument(0));
return null;
}).when(mockCache).setMessageSyncInterval(anyInt());
doAnswer(invocation -> {
searchTimeout.set(invocation.getArgument(0));
return null;
}).when(mockCache).setSearchTimeout(anyInt());
doAnswer(newSetter(lockLease, null)).when(mockCache).setLockLease(anyInt());
doAnswer(newSetter(lockTimeout, null)).when(mockCache).setLockTimeout(anyInt());
doAnswer(newSetter(messageSyncInterval, null)).when(mockCache).setMessageSyncInterval(anyInt());
doAnswer(newSetter(searchTimeout, null)).when(mockCache).setSearchTimeout(anyInt());
when(mockCache.isServer()).thenReturn(true);
when(mockCache.getCacheServers()).thenAnswer(invocation -> Collections.unmodifiableList(cacheServers));
when(mockCache.getLockLease()).thenAnswer(invocation -> lockLease.get());
when(mockCache.getLockTimeout()).thenAnswer(invocation -> lockTimeout.get());
when(mockCache.getMessageSyncInterval()).thenAnswer(invocation -> messageSyncInterval.get());
when(mockCache.getLockLease()).thenAnswer(newGetter(lockLease));
when(mockCache.getLockTimeout()).thenAnswer(newGetter(lockTimeout));
when(mockCache.getMessageSyncInterval()).thenAnswer(newGetter(messageSyncInterval));
when(mockCache.getReconnectedCache()).thenAnswer(invocation -> mockPeerCache());
when(mockCache.getSearchTimeout()).thenAnswer(invocation -> searchTimeout.get());
when(mockCache.getSearchTimeout()).thenAnswer(newGetter(searchTimeout));
return mockCacheApi(mockCache);
}
@@ -283,72 +268,50 @@ public abstract class MockGemFireObjectsSupport {
AtomicReference<String> bindAddress = new AtomicReference<>(CacheServer.DEFAULT_BIND_ADDRESS);
AtomicReference<String> hostnameForClients = new AtomicReference<>(CacheServer.DEFAULT_HOSTNAME_FOR_CLIENTS);
doAnswer(invocation -> {
bindAddress.set(invocation.getArgument(0));
return null;
}).when(mockCacheServer).setBindAddress(anyString());
doAnswer(newSetter(bindAddress, null))
.when(mockCacheServer).setBindAddress(anyString());
doAnswer(invocation -> {
hostnameForClients.set(invocation.getArgument(0));
return null;
}).when(mockCacheServer).setHostnameForClients(anyString());
doAnswer(newSetter(hostnameForClients, null))
.when(mockCacheServer).setHostnameForClients(anyString());
doAnswer(invocation -> {
loadPollInterval.set(invocation.getArgument(0));
return null;
}).when(mockCacheServer).setLoadPollInterval(anyLong());
doAnswer(newSetter(loadPollInterval, null))
.when(mockCacheServer).setLoadPollInterval(anyLong());
doAnswer(invocation -> {
maxConnections.set(invocation.getArgument(0));
return null;
}).when(mockCacheServer).setMaxConnections(anyInt());
doAnswer(newSetter(maxConnections, null))
.when(mockCacheServer).setMaxConnections(anyInt());
doAnswer(invocation -> {
maxMessageCount.set(invocation.getArgument(0));
return null;
}).when(mockCacheServer).setMaximumMessageCount(anyInt());
doAnswer(newSetter(maxMessageCount, null))
.when(mockCacheServer).setMaximumMessageCount(anyInt());
doAnswer(invocation -> {
maxThreads.set(invocation.getArgument(0));
return null;
}).when(mockCacheServer).setMaxThreads(anyInt());
doAnswer(newSetter(maxThreads, null))
.when(mockCacheServer).setMaxThreads(anyInt());
doAnswer(invocation -> {
maxTimeBetweenPings.set(invocation.getArgument(0));
return null;
}).when(mockCacheServer).setMaximumTimeBetweenPings(anyInt());
doAnswer(newSetter(maxTimeBetweenPings, null))
.when(mockCacheServer).setMaximumTimeBetweenPings(anyInt());
doAnswer(invocation -> {
messageTimeToLive.set(invocation.getArgument(0));
return null;
}).when(mockCacheServer).setMessageTimeToLive(anyInt());
doAnswer(newSetter(messageTimeToLive, null))
.when(mockCacheServer).setMessageTimeToLive(anyInt());
doAnswer(invocation -> {
port.set(invocation.getArgument(0));
return null;
}).when(mockCacheServer).setPort(anyInt());
doAnswer(newSetter(port, null))
.when(mockCacheServer).setPort(anyInt());
doAnswer(invocation -> {
socketBufferSize.set(invocation.getArgument(0));
return null;
}).when(mockCacheServer).setSocketBufferSize(anyInt());
doAnswer(newSetter(socketBufferSize, null))
.when(mockCacheServer).setSocketBufferSize(anyInt());
doAnswer(invocation -> {
tcpNoDelay.set(invocation.getArgument(0));
return null;
}).when(mockCacheServer).setTcpNoDelay(anyBoolean());
doAnswer(newSetter(tcpNoDelay, null))
.when(mockCacheServer).setTcpNoDelay(anyBoolean());
when(mockCacheServer.getBindAddress()).thenAnswer(invocation -> bindAddress.get());
when(mockCacheServer.getHostnameForClients()).thenAnswer(invocation -> hostnameForClients.get());
when(mockCacheServer.getLoadPollInterval()).thenAnswer(invocation -> loadPollInterval.get());
when(mockCacheServer.getMaxConnections()).thenAnswer(invocation -> maxConnections.get());
when(mockCacheServer.getMaximumMessageCount()).thenAnswer(invocation -> maxMessageCount.get());
when(mockCacheServer.getMaxThreads()).thenAnswer(invocation -> maxThreads.get());
when(mockCacheServer.getMaximumTimeBetweenPings()).thenAnswer(invocation -> maxTimeBetweenPings.get());
when(mockCacheServer.getMessageTimeToLive()).thenAnswer(invocation -> messageTimeToLive.get());
when(mockCacheServer.getPort()).thenAnswer(invocation -> port.get());
when(mockCacheServer.getSocketBufferSize()).thenAnswer(invocation -> socketBufferSize.get());
when(mockCacheServer.getTcpNoDelay()).thenAnswer(invocation -> tcpNoDelay.get());
when(mockCacheServer.getBindAddress()).thenAnswer(newGetter(bindAddress));
when(mockCacheServer.getHostnameForClients()).thenAnswer(newGetter(hostnameForClients));
when(mockCacheServer.getLoadPollInterval()).thenAnswer(newGetter(loadPollInterval));
when(mockCacheServer.getMaxConnections()).thenAnswer(newGetter(maxConnections));
when(mockCacheServer.getMaximumMessageCount()).thenAnswer(newGetter(maxMessageCount));
when(mockCacheServer.getMaxThreads()).thenAnswer(newGetter(maxThreads));
when(mockCacheServer.getMaximumTimeBetweenPings()).thenAnswer(newGetter(maxTimeBetweenPings));
when(mockCacheServer.getMessageTimeToLive()).thenAnswer(newGetter(messageTimeToLive));
when(mockCacheServer.getPort()).thenAnswer(newGetter(port));
when(mockCacheServer.getSocketBufferSize()).thenAnswer(newGetter(socketBufferSize));
when(mockCacheServer.getTcpNoDelay()).thenAnswer(newGetter(tcpNoDelay));
ClientSubscriptionConfig mockClientSubsriptionConfig = mockClientSubscriptionConfig();
@@ -368,26 +331,25 @@ public abstract class MockGemFireObjectsSupport {
AtomicReference<SubscriptionEvictionPolicy> subscriptionEvictionPolicy =
new AtomicReference<>(SubscriptionEvictionPolicy.DEFAULT);
doAnswer(invocation -> {
subscriptionCapacity.set(invocation.getArgument(0));
return null;
}).when(mockClientSubscriptionConfig).setCapacity(anyInt());
Function<String, SubscriptionEvictionPolicy> stringToSubscriptionEvictionPolicyConverter =
arg -> SubscriptionEvictionPolicy.valueOfIgnoreCase(String.valueOf(arg));
doAnswer(invocation -> {
subscriptionDiskStoreName.set(invocation.getArgument(0));
return null;
}).when(mockClientSubscriptionConfig).setDiskStoreName(anyString());
Function<SubscriptionEvictionPolicy, String> subscriptionEvictionPolicyToStringConverter =
arg -> Optional.ofNullable(arg).map(Object::toString).map(String::toLowerCase).orElse(null);
doAnswer(invocation -> {
subscriptionEvictionPolicy.set(SubscriptionEvictionPolicy.valueOfIgnoreCase(invocation.getArgument(0)));
return null;
}).when(mockClientSubscriptionConfig).setEvictionPolicy(anyString());
doAnswer(newSetter(subscriptionCapacity, null))
.when(mockClientSubscriptionConfig).setCapacity(anyInt());
when(mockClientSubscriptionConfig.getCapacity()).thenAnswer(invocation -> subscriptionCapacity.get());
when(mockClientSubscriptionConfig.getDiskStoreName()).thenAnswer(invocation -> subscriptionDiskStoreName.get());
when(mockClientSubscriptionConfig.getEvictionPolicy()).thenAnswer(invocation ->
Optional.ofNullable(subscriptionEvictionPolicy.get()).map(Object::toString).map(String::toLowerCase)
.orElse(null));
doAnswer(newSetter(subscriptionDiskStoreName, null))
.when(mockClientSubscriptionConfig).setDiskStoreName(anyString());
doAnswer(newSetter(subscriptionEvictionPolicy, stringToSubscriptionEvictionPolicyConverter, null))
.when(mockClientSubscriptionConfig).setEvictionPolicy(anyString());
when(mockClientSubscriptionConfig.getCapacity()).thenAnswer(newGetter(subscriptionCapacity));
when(mockClientSubscriptionConfig.getDiskStoreName()).thenAnswer(newGetter(subscriptionDiskStoreName));
when(mockClientSubscriptionConfig.getEvictionPolicy()).thenAnswer(newGetter(subscriptionEvictionPolicy,
subscriptionEvictionPolicyToStringConverter));
return mockClientSubscriptionConfig;
}
@@ -417,20 +379,14 @@ public abstract class MockGemFireObjectsSupport {
AtomicReference<Float> diskUsageWarningPercentage =
new AtomicReference<>(DiskStoreFactory.DEFAULT_DISK_USAGE_WARNING_PERCENTAGE);
when(mockDiskStoreFactory.setAllowForceCompaction(anyBoolean())).thenAnswer(invocation -> {
allowForceCompaction.set(invocation.getArgument(0));
return mockDiskStoreFactory;
});
when(mockDiskStoreFactory.setAllowForceCompaction(anyBoolean()))
.thenAnswer(newSetter(allowForceCompaction, mockDiskStoreFactory));
when(mockDiskStoreFactory.setAutoCompact(anyBoolean())).thenAnswer(invocation -> {
autoCompact.set(invocation.getArgument(0));
return mockDiskStoreFactory;
});
when(mockDiskStoreFactory.setAutoCompact(anyBoolean()))
.thenAnswer(newSetter(autoCompact, mockDiskStoreFactory));
when(mockDiskStoreFactory.setCompactionThreshold(anyInt())).thenAnswer(invocation -> {
compactionThreshold.set(invocation.getArgument(0));
return mockDiskStoreFactory;
});
when(mockDiskStoreFactory.setCompactionThreshold(anyInt()))
.thenAnswer(newSetter(compactionThreshold, mockDiskStoreFactory));
when(mockDiskStoreFactory.setDiskDirs(any(File[].class))).thenAnswer(invocation -> {
@@ -454,35 +410,23 @@ public abstract class MockGemFireObjectsSupport {
return mockDiskStoreFactory;
});
when(mockDiskStoreFactory.setDiskUsageCriticalPercentage(anyFloat())).thenAnswer(invocation -> {
diskUsageCriticalPercentage.set(invocation.getArgument(0));
return mockDiskStoreFactory;
});
when(mockDiskStoreFactory.setDiskUsageCriticalPercentage(anyFloat()))
.thenAnswer(newSetter(diskUsageCriticalPercentage, mockDiskStoreFactory));
when(mockDiskStoreFactory.setDiskUsageWarningPercentage(anyFloat())).thenAnswer(invocation -> {
diskUsageWarningPercentage.set(invocation.getArgument(0));
return mockDiskStoreFactory;
});
when(mockDiskStoreFactory.setDiskUsageWarningPercentage(anyFloat()))
.thenAnswer(newSetter(diskUsageWarningPercentage, mockDiskStoreFactory));
when(mockDiskStoreFactory.setMaxOplogSize(anyLong())).thenAnswer(invocation -> {
maxOplogSize.set(invocation.getArgument(0));
return mockDiskStoreFactory;
});
when(mockDiskStoreFactory.setMaxOplogSize(anyLong()))
.thenAnswer(newSetter(maxOplogSize, mockDiskStoreFactory));
when(mockDiskStoreFactory.setQueueSize(anyInt())).thenAnswer(invocation -> {
queueSize.set(invocation.getArgument(0));
return mockDiskStoreFactory;
});
when(mockDiskStoreFactory.setQueueSize(anyInt()))
.thenAnswer(newSetter(queueSize, mockDiskStoreFactory));
when(mockDiskStoreFactory.setTimeInterval(anyLong())).thenAnswer(invocation -> {
timeInterval.set(invocation.getArgument(0));
return mockDiskStoreFactory;
});
when(mockDiskStoreFactory.setTimeInterval(anyLong()))
.thenAnswer(newSetter(timeInterval, mockDiskStoreFactory));
when(mockDiskStoreFactory.setWriteBufferSize(anyInt())).thenAnswer(invocation -> {
writeBufferSize.set(invocation.getArgument(0));
return mockDiskStoreFactory;
});
when(mockDiskStoreFactory.setWriteBufferSize(anyInt()))
.thenAnswer(newSetter(writeBufferSize, mockDiskStoreFactory));
when(mockDiskStoreFactory.create(anyString())).thenAnswer(invocation -> {
@@ -561,95 +505,59 @@ public abstract class MockGemFireObjectsSupport {
return mockPoolFactory;
});
when(mockPoolFactory.setFreeConnectionTimeout(anyInt())).thenAnswer(invocation -> {
freeConnectionTimeout.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setFreeConnectionTimeout(anyInt()))
.thenAnswer(newSetter(freeConnectionTimeout, mockPoolFactory));
when(mockPoolFactory.setIdleTimeout(anyLong())).thenAnswer(invocation -> {
idleTimeout.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setIdleTimeout(anyLong()))
.thenAnswer(newSetter(idleTimeout, mockPoolFactory));
when(mockPoolFactory.setLoadConditioningInterval(anyInt())).thenAnswer(invocation -> {
loadConditioningInterval.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setLoadConditioningInterval(anyInt()))
.thenAnswer(newSetter(loadConditioningInterval, mockPoolFactory));
when(mockPoolFactory.setMaxConnections(anyInt())).thenAnswer(invocation -> {
maxConnections.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setMaxConnections(anyInt()))
.thenAnswer(newSetter(maxConnections, mockPoolFactory));
when(mockPoolFactory.setMinConnections(anyInt())).thenAnswer(invocation -> {
minConnections.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setMinConnections(anyInt()))
.thenAnswer(newSetter(minConnections, mockPoolFactory));
when(mockPoolFactory.setMultiuserAuthentication(anyBoolean())).thenAnswer(invocation -> {
multiuserAuthentication.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setMultiuserAuthentication(anyBoolean()))
.thenAnswer(newSetter(multiuserAuthentication, mockPoolFactory));
when(mockPoolFactory.setPingInterval(anyLong())).thenAnswer(invocation -> {
pingInterval.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setPingInterval(anyLong()))
.thenAnswer(newSetter(pingInterval, mockPoolFactory));
when(mockPoolFactory.setPRSingleHopEnabled(anyBoolean())).thenAnswer(invocation -> {
prSingleHopEnabled.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setPRSingleHopEnabled(anyBoolean()))
.thenAnswer(newSetter(prSingleHopEnabled, mockPoolFactory));
when(mockPoolFactory.setReadTimeout(anyInt())).thenAnswer(invocation -> {
readTimeout.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setReadTimeout(anyInt()))
.thenAnswer(newSetter(readTimeout, mockPoolFactory));
when(mockPoolFactory.setRetryAttempts(anyInt())).thenAnswer(invocation -> {
retryAttempts.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setRetryAttempts(anyInt()))
.thenAnswer(newSetter(retryAttempts, mockPoolFactory));
when(mockPoolFactory.setServerGroup(anyString())).thenAnswer(invocation -> {
serverGroup.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setServerGroup(anyString()))
.thenAnswer(newSetter(serverGroup, mockPoolFactory));
when(mockPoolFactory.setSocketBufferSize(anyInt())).thenAnswer(invocation -> {
socketBufferSize.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setSocketBufferSize(anyInt()))
.thenAnswer(newSetter(socketBufferSize, mockPoolFactory));
when(mockPoolFactory.setStatisticInterval(anyInt())).thenAnswer(invocation -> {
statisticInterval.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setStatisticInterval(anyInt()))
.thenAnswer(newSetter(statisticInterval, mockPoolFactory));
when(mockPoolFactory.setSubscriptionAckInterval(anyInt())).thenAnswer(invocation -> {
subscriptionAckInterval.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setSubscriptionAckInterval(anyInt()))
.thenAnswer(newSetter(subscriptionAckInterval, mockPoolFactory));
when(mockPoolFactory.setSubscriptionEnabled(anyBoolean())).thenAnswer(invocation -> {
subscriptionEnabled.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setSubscriptionEnabled(anyBoolean()))
.thenAnswer(newSetter(subscriptionEnabled, mockPoolFactory));
when(mockPoolFactory.setSubscriptionMessageTrackingTimeout(anyInt())).thenAnswer(invocation -> {
subscriptionMessageTrackingTimeout.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setSubscriptionMessageTrackingTimeout(anyInt()))
.thenAnswer(newSetter(subscriptionMessageTrackingTimeout, mockPoolFactory));
when(mockPoolFactory.setSubscriptionRedundancy(anyInt())).thenAnswer(invocation -> {
subscriptionRedundancy.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setSubscriptionRedundancy(anyInt()))
.thenAnswer(newSetter(subscriptionRedundancy, mockPoolFactory));
when(mockPoolFactory.setThreadLocalConnections(anyBoolean())).thenAnswer(invocation -> {
threadLocalConnections.set(invocation.getArgument(0));
return mockPoolFactory;
});
when(mockPoolFactory.setThreadLocalConnections(anyBoolean()))
.thenAnswer(newSetter(threadLocalConnections, mockPoolFactory));
when(mockPoolFactory.create(anyString())).thenAnswer(invocation -> {
@@ -669,7 +577,7 @@ public abstract class MockGemFireObjectsSupport {
return null;
}).when(mockPool).destroy(anyBoolean());
when(mockPool.isDestroyed()).thenAnswer(invocationOnMock -> destroyed.get());
when(mockPool.isDestroyed()).thenAnswer(newGetter(destroyed));
when(mockPool.getFreeConnectionTimeout()).thenReturn(freeConnectionTimeout.get());
when(mockPool.getIdleTimeout()).thenReturn(idleTimeout.get());
when(mockPool.getLoadConditioningInterval()).thenReturn(loadConditioningInterval.get());
@@ -715,30 +623,22 @@ public abstract class MockGemFireObjectsSupport {
AtomicReference<Float> evictionOffHeapPercentage =
new AtomicReference<>(ResourceManager.DEFAULT_EVICTION_PERCENTAGE);
doAnswer(invocation -> {
criticalHeapPercentage.set(invocation.getArgument(0));
return null;
}).when(mockResourceManager).setCriticalHeapPercentage(anyFloat());
doAnswer(newSetter(criticalHeapPercentage, null))
.when(mockResourceManager).setCriticalHeapPercentage(anyFloat());
doAnswer(invocation -> {
criticalOffHeapPercentage.set(invocation.getArgument(0));
return null;
}).when(mockResourceManager).setCriticalOffHeapPercentage(anyFloat());
doAnswer(newSetter(criticalOffHeapPercentage, null))
.when(mockResourceManager).setCriticalOffHeapPercentage(anyFloat());
doAnswer(invocation -> {
evictionHeapPercentage.set(invocation.getArgument(0));
return null;
}).when(mockResourceManager).setEvictionHeapPercentage(anyFloat());
doAnswer(newSetter(evictionHeapPercentage, null))
.when(mockResourceManager).setEvictionHeapPercentage(anyFloat());
doAnswer(invocation -> {
evictionOffHeapPercentage.set(invocation.getArgument(0));
return null;
}).when(mockResourceManager).setEvictionOffHeapPercentage(anyFloat());
doAnswer(newSetter(evictionOffHeapPercentage, null))
.when(mockResourceManager).setEvictionOffHeapPercentage(anyFloat());
when(mockResourceManager.getCriticalHeapPercentage()).thenAnswer(invocation -> criticalHeapPercentage.get());
when(mockResourceManager.getCriticalOffHeapPercentage()).thenAnswer(invocation -> criticalOffHeapPercentage.get());
when(mockResourceManager.getEvictionHeapPercentage()).thenAnswer(invocation -> evictionHeapPercentage.get());
when(mockResourceManager.getEvictionOffHeapPercentage()).thenAnswer(invocation -> evictionOffHeapPercentage.get());
when(mockResourceManager.getCriticalHeapPercentage()).thenAnswer(newGetter(criticalHeapPercentage));
when(mockResourceManager.getCriticalOffHeapPercentage()).thenAnswer(newGetter(criticalOffHeapPercentage));
when(mockResourceManager.getEvictionHeapPercentage()).thenAnswer(newGetter(evictionHeapPercentage));
when(mockResourceManager.getEvictionOffHeapPercentage()).thenAnswer(newGetter(evictionOffHeapPercentage));
when(mockResourceManager.getRebalanceOperations()).thenReturn(Collections.emptySet());
return mockResourceManager;
@@ -757,38 +657,28 @@ public abstract class MockGemFireObjectsSupport {
AtomicReference<String> pdxDiskStoreName = new AtomicReference<>(null);
AtomicReference<PdxSerializer> pdxSerializer = new AtomicReference<>(null);
doAnswer(invocation -> {
pdxDiskStoreName.set(invocation.getArgument(0));
return cacheFactorySpy;
}).when(cacheFactorySpy.setPdxDiskStore(anyString()));
doAnswer(newSetter(pdxDiskStoreName, cacheFactorySpy))
.when(cacheFactorySpy).setPdxDiskStore(anyString());
doAnswer(invocation -> {
pdxIgnoreUnreadFields.set(invocation.getArgument(0));
return cacheFactorySpy;
}).when(cacheFactorySpy.setPdxIgnoreUnreadFields(anyBoolean()));
doAnswer(newSetter(pdxIgnoreUnreadFields, cacheFactorySpy))
.when(cacheFactorySpy).setPdxIgnoreUnreadFields(anyBoolean());
doAnswer(invocation -> {
pdxPersistent.set(invocation.getArgument(0));
return cacheFactorySpy;
}).when(cacheFactorySpy.setPdxPersistent(anyBoolean()));
doAnswer(newSetter(pdxPersistent, cacheFactorySpy))
.when(cacheFactorySpy).setPdxPersistent(anyBoolean());
doAnswer(invocation -> {
pdxReadSerialized.set(invocation.getArgument(0));
return cacheFactorySpy;
}).when(cacheFactorySpy.setPdxReadSerialized(anyBoolean()));
doAnswer(newSetter(pdxReadSerialized, cacheFactorySpy))
.when(cacheFactorySpy).setPdxReadSerialized(anyBoolean());
doAnswer(invocation -> {
pdxSerializer.set(invocation.getArgument(0));
return cacheFactorySpy;
}).when(cacheFactorySpy.setPdxSerializer(any(PdxSerializer.class)));
doAnswer(newSetter(pdxSerializer, cacheFactorySpy))
.when(cacheFactorySpy).setPdxSerializer(any(PdxSerializer.class));
doReturn(mockCache).when(cacheFactorySpy.create());
doReturn(mockCache).when(cacheFactorySpy).create();
when(mockCache.getPdxDiskStore()).thenAnswer(invocation -> pdxDiskStoreName.get());
when(mockCache.getPdxIgnoreUnreadFields()).thenAnswer(invocation -> pdxIgnoreUnreadFields.get());
when(mockCache.getPdxPersistent()).thenAnswer(invocation -> pdxPersistent.get());
when(mockCache.getPdxReadSerialized()).thenAnswer(invocation -> pdxReadSerialized.get());
when(mockCache.getPdxSerializer()).thenAnswer(invocation -> pdxSerializer.get());
when(mockCache.getPdxDiskStore()).thenAnswer(newGetter(pdxDiskStoreName));
when(mockCache.getPdxIgnoreUnreadFields()).thenAnswer(newGetter(pdxIgnoreUnreadFields));
when(mockCache.getPdxPersistent()).thenAnswer(newGetter(pdxPersistent));
when(mockCache.getPdxReadSerialized()).thenAnswer(newGetter(pdxReadSerialized));
when(mockCache.getPdxSerializer()).thenAnswer(newGetter(pdxSerializer));
return cacheFactorySpy;
}
@@ -799,8 +689,6 @@ public abstract class MockGemFireObjectsSupport {
ClientCache mockClientCache = mockClientCache();
PoolFactory mockPoolFactory = mockPoolFactory();
AtomicBoolean pdxIgnoreUnreadFields = new AtomicBoolean(false);
AtomicBoolean pdxPersistent = new AtomicBoolean(false);
AtomicBoolean pdxReadSerialized = new AtomicBoolean(false);
@@ -809,132 +697,124 @@ public abstract class MockGemFireObjectsSupport {
AtomicReference<PdxSerializer> pdxSerializer = new AtomicReference<>(null);
AtomicReference<Pool> defaultPool = new AtomicReference<>(null);
doAnswer(invocation -> {
pdxDiskStoreName.set(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPdxDiskStore(anyString()));
doAnswer(newSetter(pdxDiskStoreName, clientCacheFactorySpy))
.when(clientCacheFactorySpy).setPdxDiskStore(anyString());
doAnswer(invocation -> {
pdxIgnoreUnreadFields.set(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPdxIgnoreUnreadFields(anyBoolean()));
doAnswer(newSetter(pdxIgnoreUnreadFields, clientCacheFactorySpy))
.when(clientCacheFactorySpy).setPdxIgnoreUnreadFields(anyBoolean());
doAnswer(invocation -> {
pdxPersistent.set(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPdxPersistent(anyBoolean()));
doAnswer(newSetter(pdxPersistent, clientCacheFactorySpy))
.when(clientCacheFactorySpy).setPdxPersistent(anyBoolean());
doAnswer(invocation -> {
pdxReadSerialized.set(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPdxReadSerialized(anyBoolean()));
doAnswer(newSetter(pdxReadSerialized, clientCacheFactorySpy))
.when(clientCacheFactorySpy).setPdxReadSerialized(anyBoolean());
doAnswer(invocation -> {
pdxSerializer.set(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPdxSerializer(any(PdxSerializer.class)));
doAnswer(newSetter(pdxSerializer, clientCacheFactorySpy))
.when(clientCacheFactorySpy).setPdxSerializer(any(PdxSerializer.class));
PoolFactory mockPoolFactory = mockPoolFactory();
doAnswer(invocation -> {
mockPoolFactory.addLocator(invocation.getArgument(0), invocation.getArgument(1));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.addPoolLocator(anyString(), anyInt()));
}).when(clientCacheFactorySpy).addPoolLocator(anyString(), anyInt());
doAnswer(invocation -> {
mockPoolFactory.addServer(invocation.getArgument(0), invocation.getArgument(1));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.addPoolServer(anyString(), anyInt()));
}).when(clientCacheFactorySpy).addPoolServer(anyString(), anyInt());
doAnswer(invocation -> {
mockPoolFactory.setFreeConnectionTimeout(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolFreeConnectionTimeout(anyInt()));
}).when(clientCacheFactorySpy).setPoolFreeConnectionTimeout(anyInt());
doAnswer(invocation -> {
mockPoolFactory.setIdleTimeout(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolIdleTimeout(anyLong()));
}).when(clientCacheFactorySpy).setPoolIdleTimeout(anyLong());
doAnswer(invocation -> {
mockPoolFactory.setLoadConditioningInterval(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolLoadConditioningInterval(anyInt()));
}).when(clientCacheFactorySpy).setPoolLoadConditioningInterval(anyInt());
doAnswer(invocation -> {
mockPoolFactory.setMaxConnections(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolMaxConnections(anyInt()));
}).when(clientCacheFactorySpy).setPoolMaxConnections(anyInt());
doAnswer(invocation -> {
mockPoolFactory.setMinConnections(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolMinConnections(anyInt()));
}).when(clientCacheFactorySpy).setPoolMinConnections(anyInt());
doAnswer(invocation -> {
mockPoolFactory.setMultiuserAuthentication(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolMultiuserAuthentication(anyBoolean()));
}).when(clientCacheFactorySpy).setPoolMultiuserAuthentication(anyBoolean());
doAnswer(invocation -> {
mockPoolFactory.setPingInterval(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolPingInterval(anyLong()));
}).when(clientCacheFactorySpy).setPoolPingInterval(anyLong());
doAnswer(invocation -> {
mockPoolFactory.setPRSingleHopEnabled(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolPRSingleHopEnabled(anyBoolean()));
}).when(clientCacheFactorySpy).setPoolPRSingleHopEnabled(anyBoolean());
doAnswer(invocation -> {
mockPoolFactory.setReadTimeout(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolReadTimeout(anyInt()));
}).when(clientCacheFactorySpy).setPoolReadTimeout(anyInt());
doAnswer(invocation -> {
mockPoolFactory.setRetryAttempts(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolRetryAttempts(anyInt()));
}).when(clientCacheFactorySpy).setPoolRetryAttempts(anyInt());
doAnswer(invocation -> {
mockPoolFactory.setServerGroup(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolServerGroup(anyString()));
}).when(clientCacheFactorySpy).setPoolServerGroup(anyString());
doAnswer(invocation -> {
mockPoolFactory.setSocketBufferSize(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolSocketBufferSize(anyInt()));
}).when(clientCacheFactorySpy).setPoolSocketBufferSize(anyInt());
doAnswer(invocation -> {
mockPoolFactory.setStatisticInterval(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolStatisticInterval(anyInt()));
}).when(clientCacheFactorySpy).setPoolStatisticInterval(anyInt());
doAnswer(invocation -> {
mockPoolFactory.setSubscriptionAckInterval(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolSubscriptionAckInterval(anyInt()));
}).when(clientCacheFactorySpy).setPoolSubscriptionAckInterval(anyInt());
doAnswer(invocation -> {
mockPoolFactory.setSubscriptionEnabled(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolSubscriptionEnabled(anyBoolean()));
}).when(clientCacheFactorySpy).setPoolSubscriptionEnabled(anyBoolean());
doAnswer(invocation -> {
mockPoolFactory.setSubscriptionMessageTrackingTimeout(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolSubscriptionMessageTrackingTimeout(anyInt()));
}).when(clientCacheFactorySpy).setPoolSubscriptionMessageTrackingTimeout(anyInt());
doAnswer(invocation -> {
mockPoolFactory.setSubscriptionRedundancy(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolSubscriptionRedundancy(anyInt()));
}).when(clientCacheFactorySpy).setPoolSubscriptionRedundancy(anyInt());
doAnswer(invocation -> {
mockPoolFactory.setThreadLocalConnections(invocation.getArgument(0));
return clientCacheFactorySpy;
}).when(clientCacheFactorySpy.setPoolThreadLocalConnections(anyBoolean()));
}).when(clientCacheFactorySpy).setPoolThreadLocalConnections(anyBoolean());
doReturn(mockClientCache).when(clientCacheFactorySpy.create());
doReturn(mockClientCache).when(clientCacheFactorySpy).create();
when(mockClientCache.getCurrentServers()).thenAnswer(invocation ->
Collections.unmodifiableSet(new HashSet<>(defaultPool.get().getServers())));
@@ -948,11 +828,11 @@ public abstract class MockGemFireObjectsSupport {
return defaultPool.get();
});
when(mockClientCache.getPdxDiskStore()).thenAnswer(invocation -> pdxDiskStoreName.get());
when(mockClientCache.getPdxIgnoreUnreadFields()).thenAnswer(invocation -> pdxIgnoreUnreadFields.get());
when(mockClientCache.getPdxPersistent()).thenAnswer(invocation -> pdxPersistent.get());
when(mockClientCache.getPdxReadSerialized()).thenAnswer(invocation -> pdxReadSerialized.get());
when(mockClientCache.getPdxSerializer()).thenAnswer(invocation -> pdxSerializer.get());
when(mockClientCache.getPdxDiskStore()).thenAnswer(newGetter(pdxDiskStoreName));
when(mockClientCache.getPdxIgnoreUnreadFields()).thenAnswer(newGetter(pdxIgnoreUnreadFields));
when(mockClientCache.getPdxPersistent()).thenAnswer(newGetter(pdxPersistent));
when(mockClientCache.getPdxReadSerialized()).thenAnswer(newGetter(pdxReadSerialized));
when(mockClientCache.getPdxSerializer()).thenAnswer(newGetter(pdxSerializer));
return clientCacheFactorySpy;
}

View File

@@ -0,0 +1,142 @@
/*
* 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.test.mock;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import org.mockito.stubbing.Answer;
/**
* The {@link MockObjectsSupport} class is an abstract base class encapsulating common operations and utilities
* used in mocking using Mockito.
*
* @author John Blum
* @since 2.0.0
*/
@SuppressWarnings("unused")
public abstract class MockObjectsSupport {
/* (non-Javadoc) */
protected static Answer<Boolean> newGetter(AtomicBoolean returnValue) {
return invocation -> returnValue.get();
}
/* (non-Javadoc) */
protected static Answer<Integer> newGetter(AtomicInteger returnValue) {
return invocation -> returnValue.get();
}
/* (non-Javadoc) */
protected static Answer<Long> newGetter(AtomicLong returnValue) {
return invocation -> returnValue.get();
}
/* (non-Javadoc) */
protected static <R> Answer<R> newGetter(AtomicReference<R> returnValue) {
return invocation -> returnValue.get();
}
/* (non-Javadoc) */
protected static <R, S> Answer<S> newGetter(AtomicReference<R> returnValue, Function<R, S> converter) {
return invocation -> converter.apply(returnValue.get());
}
/* (non-Javadoc) */
protected static <R> Answer<R> newSetter(AtomicBoolean argument, R returnValue) {
return invocation -> {
argument.set(invocation.getArgument(0));
return returnValue;
};
}
/* (non-Javadoc) */
protected static <R> Answer<R> newSetter(AtomicBoolean argument, Boolean value, R returnValue) {
return invocation -> {
argument.set(value);
return returnValue;
};
}
/* (non-Javadoc) */
protected static <R> Answer<R> newSetter(AtomicInteger argument, R returnValue) {
return invocation -> {
argument.set(invocation.getArgument(0));
return returnValue;
};
}
/* (non-Javadoc) */
protected static <R> Answer<R> newSetter(AtomicInteger argument, Integer value, R returnValue) {
return invocation -> {
argument.set(value);
return returnValue;
};
}
/* (non-Javadoc) */
protected static <R> Answer<R> newSetter(AtomicLong argument, R returnValue) {
return invocation -> {
argument.set(invocation.getArgument(0));
return returnValue;
};
}
/* (non-Javadoc) */
protected static <R> Answer<R> newSetter(AtomicLong argument, Long value, R returnValue) {
return invocation -> {
argument.set(value);
return returnValue;
};
}
/* (non-Javadoc) */
protected static <T, R> Answer<R> newSetter(AtomicReference<T> argument, R returnValue) {
return invocation -> {
argument.set(invocation.getArgument(0));
return returnValue;
};
}
/* (non-Javadoc) */
protected static <T, R> Answer<R> newSetter(AtomicReference<T> argument, T value, R returnValue) {
return invocation -> {
argument.set(value);
return returnValue;
};
}
/* (non-Javadoc) */
protected static <T, R> Answer<R> newSetter(AtomicReference<T> argument, Function<?, T> converter, R returnValue) {
return invocation -> {
argument.set(converter.apply(invocation.getArgument(0)));
return returnValue;
};
}
/* (non-Javadoc) */
protected static <K, V, R> Answer<R> newSetter(Map<K, V> argument, R returnValue) {
return invocation -> {
argument.put(invocation.getArgument(0), invocation.getArgument(1));
return returnValue;
};
}
}