SGF-641 - 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 7a14fcf120
commit 29f092877c
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 ->
@@ -289,6 +289,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()
@@ -297,15 +298,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()))));
}
}
@@ -442,6 +444,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
@@ -456,11 +459,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);
@@ -576,6 +582,7 @@ public class CacheFactoryBean extends AbstractFactoryBeanSupport<Cache>
* @see org.springframework.dao.DataAccessException
*/
@Override
@SuppressWarnings("all")
public DataAccessException translateExceptionIfPossible(RuntimeException exception) {
if (exception instanceof IllegalArgumentException) {
@@ -619,7 +626,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;
}
@@ -700,8 +707,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);
}
/**
@@ -713,7 +721,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() {
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.
*