SGF-492 - Improve GemFire Java-based configuration support - Iteration 1.

This commit is contained in:
John Blum
2016-05-16 12:32:15 -07:00
parent 96a5990749
commit c89fc200b5
20 changed files with 3193 additions and 48 deletions

View File

@@ -23,6 +23,23 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import com.gemstone.gemfire.GemFireCheckedException;
import com.gemstone.gemfire.GemFireException;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheClosedException;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.cache.DynamicRegionFactory;
import com.gemstone.gemfire.cache.GemFireCache;
import com.gemstone.gemfire.cache.TransactionListener;
import com.gemstone.gemfire.cache.TransactionWriter;
import com.gemstone.gemfire.cache.util.GatewayConflictResolver;
import com.gemstone.gemfire.distributed.DistributedMember;
import com.gemstone.gemfire.distributed.DistributedSystem;
import com.gemstone.gemfire.internal.datasource.ConfigProperty;
import com.gemstone.gemfire.internal.jndi.JNDIInvoker;
import com.gemstone.gemfire.pdx.PdxSerializable;
import com.gemstone.gemfire.pdx.PdxSerializer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
@@ -41,23 +58,6 @@ import org.springframework.data.gemfire.util.CollectionUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import com.gemstone.gemfire.GemFireCheckedException;
import com.gemstone.gemfire.GemFireException;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheClosedException;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.cache.DynamicRegionFactory;
import com.gemstone.gemfire.cache.GemFireCache;
import com.gemstone.gemfire.cache.TransactionListener;
import com.gemstone.gemfire.cache.TransactionWriter;
import com.gemstone.gemfire.cache.util.GatewayConflictResolver;
import com.gemstone.gemfire.distributed.DistributedMember;
import com.gemstone.gemfire.distributed.DistributedSystem;
import com.gemstone.gemfire.internal.datasource.ConfigProperty;
import com.gemstone.gemfire.internal.jndi.JNDIInvoker;
import com.gemstone.gemfire.pdx.PdxSerializable;
import com.gemstone.gemfire.pdx.PdxSerializer;
/**
* FactoryBean used to configure a GemFire peer Cache node. Allows either retrieval of an existing, opened Cache
* or the creation of a new Cache instance.
@@ -67,7 +67,7 @@ import com.gemstone.gemfire.pdx.PdxSerializer;
* {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor}, for AOP-based translation
* of native Exceptions to Spring DataAccessExceptions. Hence, the presence of this class automatically enables
* a PersistenceExceptionTranslationPostProcessor to translate GemFire Exceptions appropriately.
*
*
* @author Costin Leau
* @author David Turanski
* @author John Blum
@@ -647,7 +647,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
/**
* Sets the cache properties.
*
*
* @param properties the properties to set
*/
public void setProperties(Properties properties) {
@@ -1028,40 +1028,40 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
private String diskDirectory;
private String poolName;
public String getDiskDir() {
return diskDirectory;
}
public void setDiskDir(String diskDirectory) {
this.diskDirectory = diskDirectory;
}
public Boolean getPersistent() {
return persistent;
public String getDiskDir() {
return diskDirectory;
}
public void setPersistent(Boolean persistent) {
this.persistent = persistent;
}
public String getPoolName() {
return poolName;
public Boolean getPersistent() {
return persistent;
}
public void setPoolName(String poolName) {
this.poolName = poolName;
}
public Boolean getRegisterInterest() {
return registerInterest;
public String getPoolName() {
return poolName;
}
public void setRegisterInterest(Boolean registerInterest) {
this.registerInterest = registerInterest;
}
public Boolean getRegisterInterest() {
return registerInterest;
}
public void initializeDynamicRegionFactory() {
File localDiskDirectory = (this.diskDirectory == null ? null : new File(this.diskDirectory));
File localDiskDirectory = (this.diskDirectory != null ? new File(this.diskDirectory) : null);
DynamicRegionFactory.Config config = new DynamicRegionFactory.Config(localDiskDirectory, poolName,
persistent, registerInterest);

View File

@@ -20,6 +20,15 @@ import java.net.InetSocketAddress;
import java.util.Map;
import java.util.Properties;
import com.gemstone.gemfire.cache.CacheClosedException;
import com.gemstone.gemfire.cache.GemFireCache;
import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
import com.gemstone.gemfire.cache.client.Pool;
import com.gemstone.gemfire.cache.client.PoolManager;
import com.gemstone.gemfire.distributed.DistributedSystem;
import com.gemstone.gemfire.pdx.PdxSerializer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
@@ -36,18 +45,9 @@ import org.springframework.data.gemfire.util.SpringUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import com.gemstone.gemfire.cache.CacheClosedException;
import com.gemstone.gemfire.cache.GemFireCache;
import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
import com.gemstone.gemfire.cache.client.Pool;
import com.gemstone.gemfire.cache.client.PoolManager;
import com.gemstone.gemfire.distributed.DistributedSystem;
import com.gemstone.gemfire.pdx.PdxSerializer;
/**
* FactoryBean dedicated to creating GemFire client caches.
*
*
* @author Costin Leau
* @author Lyndon Adams
* @author John Blum
@@ -98,7 +98,6 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
private String durableClientId;
private String poolName;
private String serverGroup;
private String serverName;
@Override
protected void postProcessBeforeCacheInitialization(Properties gemfireProperties) {
@@ -782,5 +781,4 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat
public final Boolean getUseClusterConfiguration() {
return Boolean.FALSE;
}
}

View File

@@ -0,0 +1,662 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import static org.springframework.data.gemfire.CacheFactoryBean.DynamicRegionSupport;
import static org.springframework.data.gemfire.CacheFactoryBean.JndiDataSource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import com.gemstone.gemfire.cache.TransactionListener;
import com.gemstone.gemfire.cache.TransactionWriter;
import com.gemstone.gemfire.cache.util.GatewayConflictResolver;
import com.gemstone.gemfire.pdx.PdxSerializer;
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.context.annotation.Bean;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* AbstractCacheConfiguration is an abstract base class for configuring either a Pivotal GemFire/Apache Geode
* client or peer-based cache instance using Spring's, Java-based
* {@link org.springframework.context.annotation.Configuration} support.
*
* This class contain configuration settings common to both GemFire peer {@link com.gemstone.gemfire.cache.Cache caches}
* and {@link com.gemstone.gemfire.cache.client.ClientCache client caches}.
*
* @author John Blum
* @see org.springframework.beans.factory.BeanClassLoaderAware
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.context.annotation.Bean
* @see org.springframework.context.annotation.ImportAware
* @since 1.9.0
*/
@SuppressWarnings("unused")
public abstract class AbstractCacheConfiguration implements BeanFactoryAware, BeanClassLoaderAware, ImportAware {
protected static final boolean DEFAULT_CLOSE = true;
protected static final boolean DEFAULT_COPY_ON_READ = false;
protected static final boolean DEFAULT_USE_BEAN_FACTORY_LOCATOR = false;
protected static final String DEFAULT_LOG_LEVEL = "config";
protected static final String DEFAULT_NAME = "SpringDataGemFireApplication";
private boolean close = DEFAULT_CLOSE;
private boolean copyOnRead = DEFAULT_COPY_ON_READ;
private boolean useBeanFactoryLocator = DEFAULT_USE_BEAN_FACTORY_LOCATOR;
private BeanFactory beanFactory;
private Boolean pdxIgnoreUnreadFields;
private Boolean pdxPersistent;
private Boolean pdxReadSerialized;
private ClassLoader beanClassLoader;
private DynamicRegionSupport dynamicRegionSupport;
private Float criticalHeapPercentage;
private Float evictionHeapPercentage;
private GatewayConflictResolver gatewayConflictResolver;
private List<JndiDataSource> jndiDataSources;
private List<TransactionListener> transactionListeners;
private PdxSerializer pdxSerializer;
private Resource cacheXml;
private String locators = "";
private String logLevel = DEFAULT_LOG_LEVEL;
private String name;
private String pdxDiskStoreName;
private TransactionWriter transactionWriter;
/**
* Returns the given {@link List} if not null or an empty {@link List}.
*
* @param <T> Class type of the elements in the {@link List}.
* @param list {@link List} on which to perform the null check.
* @return the given {@link List} if not null or an empty {@link List}.
* @see java.util.Collections#emptyList()
* @see java.util.List
*/
protected static <T> List<T> nullSafeList(List<T> list) {
return (list != null ? list : Collections.<T>emptyList());
}
/**
* Returns the given {@link Set} if not null or an empty {@link Set}.
*
* @param <T> Class type of the elements in the {@link Set}.
* @param set {@link Set} on which to perform the null check.
* @return the given {@link Set} if not null or an empty {@link Set}.
* @see java.util.Collections#emptySet()
* @see java.util.Set
*/
protected static <T> Set<T> nullSafeSet(Set<T> set) {
return (set != null ? set : Collections.<T>emptySet());
}
/**
* Returns the given {@code value} if not null or the {@code defaultValue}.
*
* @param <T> Class type of the given {@code value} and {@code defaultValue}.
* @param value value on which to perform the null check.
* @param defaultValue value to return by default if the {@code value} is null.
* @return the given {@code value} if not null or the {@code defaultValue}.
*/
protected static <T> T nullSafeValue(T value, T defaultValue) {
return (value != null ? value : defaultValue);
}
/**
* Determines whether the give {@link Object} has value. The {@link Object} is valuable
* if it is not {@literal null}.
*
* @param value {@link Object} to evaluate.
* @return a boolean value indicating whether the given {@link Object} has value.
*/
protected static boolean hasValue(Object value) {
return (value != null);
}
/**
* Determines whether the given {@link Number} has value. The {@link Number} is valuable
* if it is not {@literal null} and is not equal to 0.0d.
*
* @param value {@link Number} to evaluate.
* @return a boolean value indicating whether the given {@link Number} has value.
*/
protected static boolean hasValue(Number value) {
return (value != null && value.doubleValue() != 0.0d);
}
/**
* Determines whether the given {@link String} has value. The {@link String} is valuable
* if it is not {@literal null} or empty.
*
* @param value {@link String} to evaluate.
* @return a boolean value indicating whether the given {@link String} is valuable.
*/
protected static boolean hasValue(String value) {
return StringUtils.hasText(value);
}
/**
* Returns a {@link Properties} object containing GemFire System properties used to configure
* the GemFire cache.
*
* The name of the GemFire member/node is set to a pre-dined, descriptive default value depending
* on the type configuraiton applied.
*
* Both 'mcast-port' and 'locators' are to set 0 and empty String respectively, which is necessary
* for {@link com.gemstone.gemfire.cache.client.ClientCache cache client}-based applications.
*
* Finally GemFire's "log-level" System property defaults to "config".
*
* @return a {@link Properties} object containing GemFire System properties used to configure
* the GemFire cache.
* @see <a link="http://gemfire.docs.pivotal.io/docs-gemfire/reference/topics/gemfire_properties.html">GemFire Properties</a>
* @see java.util.Properties
* @see #name()
* @see #logLevel()
* @see #locators()
*/
@Bean
protected Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("name", name());
gemfireProperties.setProperty("mcast-port", "0");
gemfireProperties.setProperty("log-level", logLevel());
gemfireProperties.setProperty("locators", locators());
return gemfireProperties;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.BeanClassLoaderAware
*/
@Override
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = beanClassLoader;
}
/**
* Gets a reference to the {@link ClassLoader} use by the Spring {@link BeanFactory} to load classes
* for bean definitions.
*
* @return the {@link ClassLoader} used by the Spring {@link BeanFactory} to load classes for bean definitions.
* @see #setBeanClassLoader(ClassLoader)
*/
protected ClassLoader beanClassLoader() {
return beanClassLoader;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.BeanFactoryAware
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
/**
* Gets a reference to the Spring {@link BeanFactory} in the current application context.
*
* @return a reference to the Spring {@link BeanFactory}.
* @throws IllegalStateException if the Spring {@link BeanFactory} was not properly initialized.
* @see org.springframework.beans.factory.BeanFactory
*/
protected BeanFactory beanFactory() {
Assert.state(this.beanFactory != null, "BeanFactory was not properly initialized");
return this.beanFactory;
}
/*
* (non-Javadoc)
* @see org.springframework.context.annotation.ImportAware
* @see org.springframework.core.type.AnnotationMetadata
*/
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
configureCache(importMetadata);
configurePdx(importMetadata);
configureOther(importMetadata);
}
/**
* Configures the GemFire cache settings.
*
* @param importMetadata {@link AnnotationMetadata} containing the cache meta-data used to configure
* the GemFire cache.
* @see org.springframework.core.type.AnnotationMetadata
*/
protected void configureCache(AnnotationMetadata importMetadata) {
if (isClientPeerOrServerCacheApplication(importMetadata)) {
Map<String, Object> cacheMetadataAttributes =
importMetadata.getAnnotationAttributes(getAnnotationTypeName());
setCopyOnRead(Boolean.TRUE.equals(cacheMetadataAttributes.get("copyOnRead")));
Float criticalHeapPercentage = (Float) cacheMetadataAttributes.get("criticalHeapPercentage");
if (hasValue(criticalHeapPercentage)) {
setCriticalHeapPercentage(criticalHeapPercentage);
}
Float evictionHeapPercentage = (Float) cacheMetadataAttributes.get("evictionHeapPercentage");
if (hasValue(evictionHeapPercentage)) {
setEvictionHeapPercentage(evictionHeapPercentage);
}
setLogLevel((String) cacheMetadataAttributes.get("logLevel"));
setName((String) cacheMetadataAttributes.get("name"));
}
}
/**
* Configures GemFire's PDX Serialization feature.
*
* @param importMetadata {@link AnnotationMetadata} containing PDX meta-data used to configure
* the GemFire cache with PDX de/serialization capabilities.
* @see org.springframework.core.type.AnnotationMetadata
* @see <a href="http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/data_serialization/gemfire_pdx_serialization.html">GemFire PDX Serialization</a>
*/
protected void configurePdx(AnnotationMetadata importMetadata) {
if (importMetadata.hasAnnotation(EnablePdx.class.getName())) {
Map<String, Object> enablePdxAttributes = importMetadata.getAnnotationAttributes(EnablePdx.class.getName());
String pdxSerializerBeanName = (String) enablePdxAttributes.get("serializerBeanName");
if (beanFactory().containsBean(pdxSerializerBeanName)) {
PdxSerializer pdxSerializer = beanFactory().getBean(pdxSerializerBeanName, PdxSerializer.class);
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")));
setPdxSerializer(pdxSerializer);
}
}
}
/**
* Callback method to configure other, specific GemFire cache configuration settings.
*
* @param importMetadata {@link AnnotationMetadata} containing the cache meta-data used to configure
* the GemFire cache.
* @see org.springframework.core.type.AnnotationMetadata
*/
protected void configureOther(AnnotationMetadata importMetadata) {
}
/**
* Returns the GemFire cache application {@link java.lang.annotation.Annotation} type pertaining to
* this configuration.
*
* @return the GemFire cache application {@link java.lang.annotation.Annotation} type used by this application.
* @see org.springframework.data.gemfire.config.annotation.CacheServerApplication
* @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication
* @see org.springframework.data.gemfire.config.annotation.PeerCacheApplication
*/
protected abstract Class getAnnotationType();
/**
* Returns the fully-qualified class name of the GemFire cache application {@link java.lang.annotation.Annotation}
* type.
*
* @return the fully-qualified class name of the GemFire cache application {@link java.lang.annotation.Annotation}
* type.
* @see java.lang.Class#getName()
* @see #getAnnotationType()
*/
protected String getAnnotationTypeName() {
return getAnnotationType().getName();
}
/**
* Returns the simple class name of the GemFire cache application {@link java.lang.annotation.Annotation} type.
*
* @return the simple class name of the GemFire cache application {@link java.lang.annotation.Annotation} type.
* @see java.lang.Class#getSimpleName()
* @see #getAnnotationType()
*/
protected String getAnnotationTypeSimpleName() {
return getAnnotationType().getSimpleName();
}
/**
* Determines whether this is a GemFire {@link com.gemstone.gemfire.cache.server.CacheServer} application,
* which is indicated by the presence of the {@link CacheServerApplication} annotation on a Spring application
* {@link org.springframework.context.annotation.Configuration @Configuration} class.
*
* @param importMetadata {@link AnnotationMetadata} containing application configuration meta-data
* from the annotations used to configure the Spring application.
* @return a boolean value indicating whether this is a GemFire cache server application.
* @see org.springframework.data.gemfire.config.annotation.CacheServerApplication
* @see #getAnnotationTypeName()
* @see #getAnnotationType()
*/
protected boolean isCacheServerApplication(AnnotationMetadata importMetadata) {
return (CacheServerApplication.class.equals(getAnnotationType())
&& importMetadata.hasAnnotation(getAnnotationTypeName()));
}
/**
* Determines whether this is a GemFire {@link com.gemstone.gemfire.cache.client.ClientCache} application,
* which is indicated by the presence of the {@link ClientCacheApplication} annotation on a Spring application
* {@link org.springframework.context.annotation.Configuration @Configuration} class.
*
* @param importMetadata {@link AnnotationMetadata} containing application configuration meta-data
* from the annotations used to configure the Spring application.
* @return a boolean value indicating whether this is a GemFire cache client application.
* @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication
* @see #getAnnotationTypeName()
* @see #getAnnotationType()
*/
protected boolean isClientCacheApplication(AnnotationMetadata importMetadata) {
return (ClientCacheApplication.class.equals(getAnnotationType())
&& importMetadata.hasAnnotation(getAnnotationTypeName()));
}
/**
* Determines whether this is a GemFire peer {@link com.gemstone.gemfire.cache.Cache} application,
* which is indicated by the presence of the {@link PeerCacheApplication} annotation on a Spring application
* {@link org.springframework.context.annotation.Configuration @Configuration} class.
*
* @param importMetadata {@link AnnotationMetadata} containing application configuration meta-data
* from the annotations used to configure the Spring application.
* @return a boolean value indicating whether this is a GemFire peer cache application.
* @see org.springframework.data.gemfire.config.annotation.PeerCacheApplication
* @see #getAnnotationTypeName()
* @see #getAnnotationType()
*/
protected boolean isPeerCacheApplication(AnnotationMetadata importMetadata) {
return (PeerCacheApplication.class.equals(getAnnotationType())
&& importMetadata.hasAnnotation(getAnnotationTypeName()));
}
/**
* Determine whether this Spring application is a {@link com.gemstone.gemfire.cache.server.CacheServer},
* {@link com.gemstone.gemfire.cache.client.ClientCache} or a {@link com.gemstone.gemfire.cache.Cache} application
*
* @param importMetadata {@link AnnotationMetadata} containing application configuration meta-data
* from the annotations used to configure the Spring application.
* @return a boolean value indicating whether this is a GemFire cache server, client cache or peer cache,
* Spring application.
* @see #isCacheServerApplication(AnnotationMetadata)
* @see #isClientCacheApplication(AnnotationMetadata)
* @see #isPeerCacheApplication(AnnotationMetadata)
*/
protected boolean isClientPeerOrServerCacheApplication(AnnotationMetadata importMetadata) {
return (isCacheServerApplication(importMetadata) || isClientCacheApplication(importMetadata)
|| isPeerCacheApplication(importMetadata));
}
/**
* Constructs a new, initialized instance of the {@link CacheFactoryBean} based on the application
* GemFire cache type (i.e. client or peer).
*
* @param <T> Class type of the {@link CacheFactoryBean}.
* @return a new instance of the {@link CacheFactoryBean} for the particular application GemFire cache type
* (i.e client or peer).
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
* @see org.springframework.data.gemfire.CacheFactoryBean
* @see #setCommonCacheConfiguration(CacheFactoryBean)
* @see #newCacheFactoryBean()
*/
protected <T extends CacheFactoryBean> T constructCacheFactoryBean() {
return setCommonCacheConfiguration(this.<T>newCacheFactoryBean());
}
/**
* Constructs a new, uninitialized instance of the {@link CacheFactoryBean} based on the application
* GemFire cache type (i.e. client or peer).
*
* @param <T> Class type of the {@link CacheFactoryBean}.
* @return a new instance of the {@link CacheFactoryBean} for the particular application GemFire cache type
* (i.e client or peer).
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
* @see org.springframework.data.gemfire.CacheFactoryBean
*/
protected abstract <T extends CacheFactoryBean> T newCacheFactoryBean();
/**
* Configures common GemFire cache configuration settings.
*
* @param <T> Class type of the {@link CacheFactoryBean}.
* @param gemfireCache specific {@link CacheFactoryBean} instance to configure.
* @return the given {@link CacheFactoryBean} after common configuration settings have been applied.
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
* @see org.springframework.data.gemfire.CacheFactoryBean
*/
protected <T extends CacheFactoryBean> T setCommonCacheConfiguration(T gemfireCache) {
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.setProperties(gemfireProperties());
gemfireCache.setPdxDiskStoreName(pdxDiskStoreName());
gemfireCache.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields());
gemfireCache.setPdxPersistent(pdxPersistent());
gemfireCache.setPdxReadSerialized(pdxReadSerialized());
gemfireCache.setPdxSerializer(pdxSerializer());
gemfireCache.setTransactionListeners(transactionListeners());
gemfireCache.setTransactionWriter(transactionWriter());
return gemfireCache;
}
/* (non-Javadoc) */
void setCacheXml(Resource cacheXml) {
this.cacheXml = cacheXml;
}
protected Resource cacheXml() {
return this.cacheXml;
}
/* (non-Javadoc) */
void setClose(boolean close) {
this.close = close;
}
protected boolean close() {
return this.close;
}
/* (non-Javadoc) */
void setCopyOnRead(boolean copyOnRead) {
this.copyOnRead = copyOnRead;
}
protected boolean copyOnRead() {
return this.copyOnRead;
}
/* (non-Javadoc) */
void setCriticalHeapPercentage(Float criticalHeapPercentage) {
this.criticalHeapPercentage = criticalHeapPercentage;
}
protected Float criticalHeapPercentage() {
return this.criticalHeapPercentage;
}
/* (non-Javadoc) */
void setDynamicRegionSupport(DynamicRegionSupport dynamicRegionSupport) {
this.dynamicRegionSupport = dynamicRegionSupport;
}
protected DynamicRegionSupport dynamicRegionSupport() {
return this.dynamicRegionSupport;
}
/* (non-Javadoc) */
void setEvictionHeapPercentage(Float evictionHeapPercentage) {
this.evictionHeapPercentage = evictionHeapPercentage;
}
protected Float evictionHeapPercentage() {
return this.evictionHeapPercentage;
}
/* (non-Javadoc) */
void setGatewayConflictResolver(GatewayConflictResolver gatewayConflictResolver) {
this.gatewayConflictResolver = gatewayConflictResolver;
}
protected GatewayConflictResolver gatewayConflictResolver() {
return this.gatewayConflictResolver;
}
/* (non-Javadoc) */
void setJndiDataSources(List<JndiDataSource> jndiDataSources) {
this.jndiDataSources = jndiDataSources;
}
protected List<CacheFactoryBean.JndiDataSource> jndiDataSources() {
return nullSafeList(this.jndiDataSources);
}
void setLocators(String locators) {
this.locators = locators;
}
protected String locators() {
return this.locators;
}
/* (non-Javadoc) */
void setLogLevel(String logLevel) {
this.logLevel = logLevel;
}
protected String logLevel() {
return nullSafeValue(this.logLevel, DEFAULT_LOG_LEVEL);
}
void setName(String name) {
this.name = name;
}
protected String name() {
return (StringUtils.hasText(name) ? name : toString());
}
/* (non-Javadoc) */
void setPdxDiskStoreName(String pdxDiskStoreName) {
this.pdxDiskStoreName = pdxDiskStoreName;
}
protected String pdxDiskStoreName() {
return this.pdxDiskStoreName;
}
/* (non-Javadoc) */
void setPdxIgnoreUnreadFields(Boolean pdxIgnoreUnreadFields) {
this.pdxIgnoreUnreadFields = pdxIgnoreUnreadFields;
}
protected Boolean pdxIgnoreUnreadFields() {
return this.pdxIgnoreUnreadFields;
}
/* (non-Javadoc) */
void setPdxPersistent(Boolean pdxPersistent) {
this.pdxPersistent = pdxPersistent;
}
protected Boolean pdxPersistent() {
return this.pdxPersistent;
}
/* (non-Javadoc) */
void setPdxReadSerialized(Boolean pdxReadSerialized) {
this.pdxReadSerialized = pdxReadSerialized;
}
protected Boolean pdxReadSerialized() {
return this.pdxReadSerialized;
}
/* (non-Javadoc) */
void setPdxSerializer(PdxSerializer pdxSerializer) {
this.pdxSerializer = pdxSerializer;
}
protected PdxSerializer pdxSerializer() {
return this.pdxSerializer;
}
/* (non-Javadoc) */
void setTransactionListeners(List<TransactionListener> transactionListeners) {
this.transactionListeners = transactionListeners;
}
protected List<TransactionListener> transactionListeners() {
return nullSafeList(this.transactionListeners);
}
/* (non-Javadoc) */
void setTransactionWriter(TransactionWriter transactionWriter) {
this.transactionWriter = transactionWriter;
}
protected TransactionWriter transactionWriter() {
return this.transactionWriter;
}
/* (non-Javadoc) */
void setUseBeanFactoryLocator(boolean useBeanFactoryLocator) {
this.useBeanFactoryLocator = useBeanFactoryLocator;
}
protected boolean useBeanFactoryLocator() {
return this.useBeanFactoryLocator;
}
@Override
public String toString() {
return DEFAULT_NAME;
}
}

View File

@@ -0,0 +1,245 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.gemstone.gemfire.cache.control.ResourceManager;
import com.gemstone.gemfire.cache.server.CacheServer;
import com.gemstone.gemfire.cache.server.ClientSubscriptionConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.gemfire.server.SubscriptionEvictionPolicy;
/**
* The CacheServerApplication annotation enables an embedded GemFire
* {@link com.gemstone.gemfire.cache.server.CacheServer} instance in a Spring Data GemFire based application.
*
* In addition, this also implies an embedded GemFire peer {@link com.gemstone.gemfire.cache.Cache} must exist
* and therefore will be configured, constructed and initialized as a Spring bean in the application context.
*
* @author John Blum
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.PeerCacheConfiguration
* @see com.gemstone.gemfire.cache.control.ResourceManager
* @see com.gemstone.gemfire.cache.server.CacheServer
* @see com.gemstone.gemfire.cache.server.ClientSubscriptionConfig
* @since 1.9.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@Import(CacheServerConfiguration.class)
@SuppressWarnings("unused")
public @interface CacheServerApplication {
/**
* Configures whether the {@link CacheServer} should start automatically at runtime.
*
* Default is {@code true).
*/
boolean autoStartup() default true;
/**
* Configures the ip address or host name that this cache server will listen on.
*
* @see com.gemstone.gemfire.cache.server.CacheServer#DEFAULT_BIND_ADDRESS
*/
String bindAddress() default "localhost";
/**
* Indicates whether the "copy on read" is enabled for this cache.
*
* Default is {@code false}.
*/
boolean copyOnRead() default false;
/**
* Configures the percentage of heap at or above which the cache is considered in danger of becoming inoperable.
*
* @see com.gemstone.gemfire.cache.control.ResourceManager#DEFAULT_CRITICAL_HEAP_PERCENTAGE
*/
float criticalHeapPercentage() default ResourceManager.DEFAULT_CRITICAL_HEAP_PERCENTAGE;
/**
* By default, a GemFire member (both locators and servers) will attempt to reconnect and reinitialize the cache
* 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 {@code false}.
*/
boolean enableAutoReconnect() default false;
/**
* Configures the percentage of heap at or above which the eviction should begin on Regions configured
* for HeapLRU eviction.
*
* @see com.gemstone.gemfire.cache.control.ResourceManager#DEFAULT_EVICTION_HEAP_PERCENTAGE
*/
float evictionHeapPercentage() default ResourceManager.DEFAULT_EVICTION_HEAP_PERCENTAGE;
/**
* Configures the ip address or host name that server locators will tell clients that this cache server
* is listening on.
*
* @see com.gemstone.gemfire.cache.server.CacheServer#DEFAULT_HOSTNAME_FOR_CLIENTS
*/
String hostnameForClients() default CacheServer.DEFAULT_HOSTNAME_FOR_CLIENTS;
/**
* Configures the frequency in milliseconds to poll the load probe on this cache server.
*
* @see com.gemstone.gemfire.cache.server.CacheServer#DEFAULT_LOAD_POLL_INTERVAL
*/
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.
*/
String locators() default "";
/**
* Configures the length, in seconds, of distributed lock leases obtained by this cache.
*
* Default is {@literal 120} seconds.
*/
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
*/
int lockTimeout() default 60;
/**
* Configures the log level used to output log messages at GemFire cache runtime.
*
* Default is {@literal config}.
*/
String logLevel() default CacheServerConfiguration.DEFAULT_LOG_LEVEL;
/**
* Configures the maximum allowed client connections.
*
* @see com.gemstone.gemfire.cache.server.CacheServer#DEFAULT_MAX_CONNECTIONS
*/
int maxConnections() default CacheServer.DEFAULT_MAX_CONNECTIONS;
/**
* Configures he maximum number of messages that can be enqueued in a client-queue.
*
* @see com.gemstone.gemfire.cache.server.CacheServer#DEFAULT_MAXIMUM_MESSAGE_COUNT
*/
int maxMessageCount() default CacheServer.DEFAULT_MAXIMUM_MESSAGE_COUNT;
/**
* Configures the maximum number of threads allowed in this cache server to service client requests.
*
* @see com.gemstone.gemfire.cache.server.CacheServer#DEFAULT_MAX_THREADS
*/
int maxThreads() default CacheServer.DEFAULT_MAX_THREADS;
/**
* Configures the maximum amount of time between client pings.
*
* @see com.gemstone.gemfire.cache.server.CacheServer#DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS
*/
int maxTimeBetweenPings() default CacheServer.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS;
/**
* 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.
*/
int messageSyncInterval() default 1;
/**
* Configures the time (in seconds ) after which a message in the client queue will expire.
*
* @see com.gemstone.gemfire.cache.server.CacheServer#DEFAULT_MESSAGE_TIME_TO_LIVE
*/
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}.
*/
String name() default CacheServerConfiguration.DEFAULT_NAME;
/**
* Configures the port on which this cache server listens for clients.
*
* @see com.gemstone.gemfire.cache.server.CacheServer#DEFAULT_PORT
*/
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.
*/
int searchTimeout() default 300;
/**
* Configures the configured buffer size of the socket connection for this CacheServer.
*
* @see com.gemstone.gemfire.cache.server.CacheServer#DEFAULT_SOCKET_BUFFER_SIZE
*/
int socketBufferSize() default CacheServer.DEFAULT_SOCKET_BUFFER_SIZE;
/**
* Configures the capacity of the client queue.
*
* @see com.gemstone.gemfire.cache.server.ClientSubscriptionConfig#DEFAULT_CAPACITY
*/
int subscriptionCapacity() default ClientSubscriptionConfig.DEFAULT_CAPACITY;
/**
* Configures the disk store name for overflow.
*/
String subscriptionDiskStoreName() default "";
/**
* Configures the eviction policy that is executed when capacity of the client queue is reached.
*
* Defaults to {@link SubscriptionEvictionPolicy#NONE}.
*/
SubscriptionEvictionPolicy subscriptionEvictionPolicy() default SubscriptionEvictionPolicy.NONE;
/**
* Configures whether this GemFire cache member node would pull it's configuration meta-data
* from the cluster-based Cluster Configuration service.
*
* Default is {@code false}.
*/
boolean useClusterConfiguration() default false;
}

View File

@@ -0,0 +1,289 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Set;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.InterestRegistrationListener;
import com.gemstone.gemfire.cache.server.CacheServer;
import com.gemstone.gemfire.cache.server.ClientSubscriptionConfig;
import com.gemstone.gemfire.cache.server.ServerLoadProbe;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.server.CacheServerFactoryBean;
import org.springframework.data.gemfire.server.SubscriptionEvictionPolicy;
/**
* Spring {@link Configuration} class used to configure, construct and initialize and GemFire {@link CacheServer}
* instance in a Spring application context.
*
* @author John Blum
* @see org.springframework.context.annotation.Bean
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.data.gemfire.config.annotation.PeerCacheConfiguration
* @see com.gemstone.gemfire.cache.Cache
* @see com.gemstone.gemfire.cache.server.CacheServer
* @since 1.9.0
*/
@Configuration
@SuppressWarnings("unused")
public class CacheServerConfiguration extends PeerCacheConfiguration {
protected static final boolean DEFAULT_AUTO_STARTUP = true;
protected static final String DEFAULT_NAME = "SpringBasedCacheServerApplication";
private boolean autoStartup = DEFAULT_AUTO_STARTUP;
private Integer maxConnections;
private Integer maxMessageCount;
private Integer maxThreads;
private Integer maxTimeBetweenPings;
private Integer messageTimeToLive;
private Integer port;
private Integer socketBufferSize;
private Integer subscriptionCapacity;
private Long loadPollInterval;
private ServerLoadProbe serverLoadProbe;
private Set<InterestRegistrationListener> interestRegistrationListeners;
private String bindAddress;
private String hostnameForClients;
private String subscriptionDiskStoreName;
private SubscriptionEvictionPolicy subscriptionEvictionPolicy;
@Bean
public CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache) {
CacheServerFactoryBean gemfireCacheServer = new CacheServerFactoryBean();
gemfireCacheServer.setCache(gemfireCache);
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());
return gemfireCacheServer;
}
/**
* Configures GemFire {@link CacheServer} specific settings.
*
* @param importMetadata {@link AnnotationMetadata} containing cache server meta-data used to configure
* the GemFire {@link CacheServer}.
* @see org.springframework.core.type.AnnotationMetadata
*/
@Override
protected void configureOther(AnnotationMetadata importMetadata) {
super.configureCache(importMetadata);
if (isCacheServerApplication(importMetadata)) {
Map<String, Object> cacheServerApplicationMetadata =
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"));
}
}
@Override
protected Class getAnnotationType() {
return CacheServerApplication.class;
}
/* (non-Javadoc) */
void setAutoStartup(boolean autoStartup) {
this.autoStartup = autoStartup;
}
protected boolean autoStartup() {
return this.autoStartup;
}
/* (non-Javadoc) */
void setBindAddress(String bindAddress) {
this.bindAddress = bindAddress;
}
protected String bindAddress() {
return nullSafeValue(this.bindAddress, CacheServer.DEFAULT_BIND_ADDRESS);
}
/* (non-Javadoc) */
void setHostnameForClients(String hostnameForClients) {
this.hostnameForClients = hostnameForClients;
}
protected String hostnameForClients() {
return nullSafeValue(this.hostnameForClients, CacheServer.DEFAULT_HOSTNAME_FOR_CLIENTS);
}
/* (non-Javadoc) */
void setInterestRegistrationListeners(Set<InterestRegistrationListener> interestRegistrationListeners) {
this.interestRegistrationListeners = interestRegistrationListeners;
}
protected Set<InterestRegistrationListener> interestRegistrationListeners() {
return nullSafeSet(this.interestRegistrationListeners);
}
/* (non-Javadoc) */
void setLoadPollInterval(Long loadPollInterval) {
this.loadPollInterval = loadPollInterval;
}
protected Long loadPollInterval() {
return nullSafeValue(this.loadPollInterval, CacheServer.DEFAULT_LOAD_POLL_INTERVAL);
}
/* (non-Javadoc) */
void setMaxConnections(Integer maxConnections) {
this.maxConnections = maxConnections;
}
protected Integer maxConnections() {
return nullSafeValue(this.maxConnections, CacheServer.DEFAULT_MAX_CONNECTIONS);
}
/* (non-Javadoc) */
void setMaxMessageCount(Integer maxMessageCount) {
this.maxMessageCount = maxMessageCount;
}
protected Integer maxMessageCount() {
return nullSafeValue(this.maxMessageCount, CacheServer.DEFAULT_MAXIMUM_MESSAGE_COUNT);
}
/* (non-Javadoc) */
void setMaxThreads(Integer maxThreads) {
this.maxThreads = maxThreads;
}
protected Integer maxThreads() {
return nullSafeValue(this.maxThreads, CacheServer.DEFAULT_MAX_THREADS);
}
/* (non-Javadoc) */
void setMaxTimeBetweenPings(Integer maxTimeBetweenPings) {
this.maxTimeBetweenPings = maxTimeBetweenPings;
}
protected Integer maxTimeBetweenPings() {
return nullSafeValue(this.maxTimeBetweenPings, CacheServer.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS);
}
/* (non-Javadoc) */
void setMessageTimeToLive(Integer messageTimeToLive) {
this.messageTimeToLive = messageTimeToLive;
}
protected Integer messageTimeToLive() {
return nullSafeValue(this.messageTimeToLive, CacheServer.DEFAULT_MESSAGE_TIME_TO_LIVE);
}
/* (non-Javadoc) */
void setPort(Integer port) {
this.port = port;
}
protected Integer port() {
return nullSafeValue(this.port, CacheServer.DEFAULT_PORT);
}
/* (non-Javadoc) */
void setServerLoadProbe(ServerLoadProbe serverLoadProbe) {
this.serverLoadProbe = serverLoadProbe;
}
protected ServerLoadProbe serverLoadProbe() {
return nullSafeValue(this.serverLoadProbe, CacheServer.DEFAULT_LOAD_PROBE);
}
/* (non-Javadoc) */
void setSocketBufferSize(Integer socketBufferSize) {
this.socketBufferSize = socketBufferSize;
}
protected Integer socketBufferSize() {
return nullSafeValue(this.socketBufferSize, CacheServer.DEFAULT_SOCKET_BUFFER_SIZE);
}
/* (non-Javadoc) */
void setSubscriptionCapacity(Integer subscriptionCapacity) {
this.subscriptionCapacity = subscriptionCapacity;
}
protected Integer subscriptionCapacity() {
return nullSafeValue(this.subscriptionCapacity, ClientSubscriptionConfig.DEFAULT_CAPACITY);
}
/* (non-Javadoc) */
void setSubscriptionDiskStoreName(String subscriptionDiskStoreName) {
this.subscriptionDiskStoreName = subscriptionDiskStoreName;
}
protected String subscriptionDiskStoreName() {
return this.subscriptionDiskStoreName;
}
/* (non-Javadoc) */
void setSubscriptionEvictionPolicy(SubscriptionEvictionPolicy subscriptionEvictionPolicy) {
this.subscriptionEvictionPolicy = subscriptionEvictionPolicy;
}
protected SubscriptionEvictionPolicy subscriptionEvictionPolicy() {
return nullSafeValue(this.subscriptionEvictionPolicy, SubscriptionEvictionPolicy.DEFAULT);
}
@Override
public String toString() {
return DEFAULT_NAME;
}
}

View File

@@ -0,0 +1,275 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.gemstone.gemfire.cache.client.PoolFactory;
import com.gemstone.gemfire.cache.control.ResourceManager;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.gemfire.GemfireUtils;
/**
* The ClientCacheApplication annotation enables a Spring Data GemFire based application to become
* a GemFire cache client (i.e. {@link com.gemstone.gemfire.cache.client.ClientCache}).
*
* @author John Blum
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.PeerCacheConfiguration
* @see com.gemstone.gemfire.cache.client.PoolFactory
* @see com.gemstone.gemfire.cache.control.ResourceManager
* @since 1.9.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@Import(ClientCacheConfiguration.class)
@SuppressWarnings("unused")
public @interface ClientCacheApplication {
/**
* Indicates whether the "copy on read" is enabled for this cache.
*
* Default is {@code false}.
*/
boolean copyOnRead() default false;
/**
* Configures the percentage of heap at or above which the cache is considered in danger of becoming inoperable.
*
* @see com.gemstone.gemfire.cache.control.ResourceManager#DEFAULT_CRITICAL_HEAP_PERCENTAGE
*/
float criticalHeapPercentage() default ResourceManager.DEFAULT_CRITICAL_HEAP_PERCENTAGE;
/**
* 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.
*/
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.
*/
int durableClientTimeout() default 300;
/**
* Configures the percentage of heap at or above which the eviction should begin on Regions configured
* for HeapLRU eviction.
*
* @see com.gemstone.gemfire.cache.control.ResourceManager#DEFAULT_EVICTION_HEAP_PERCENTAGE
*/
float evictionHeapPercentage() default ResourceManager.DEFAULT_EVICTION_HEAP_PERCENTAGE;
/**
* Configures the free connection timeout for this pool.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_FREE_CONNECTION_TIMEOUT
*/
int freeConnectionTimeout() default PoolFactory.DEFAULT_FREE_CONNECTION_TIMEOUT;
/**
* Conifgures the amount of time a connection can be idle before expiring the connection.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_IDLE_TIMEOUT
*/
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 {@code false}.
*/
boolean keepAlive() default false;
/**
* Configures the load conditioning interval for this pool.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_LOAD_CONDITIONING_INTERVAL
*/
int loadConditionInterval() default PoolFactory.DEFAULT_LOAD_CONDITIONING_INTERVAL;
/**
* Configures the GemFire {@link com.gemstone.gemfire.distributed.Locator}s to which
* this cache client will connect.
*/
Locator[] locators() default {};
/**
* Configures the log level used to output log messages at GemFire cache runtime.
*
* Default is {@literal config}.
*/
String logLevel() default ClientCacheConfiguration.DEFAULT_LOG_LEVEL;
/**
* Configures the max number of client to server connections that the pool will create.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_MAX_CONNECTIONS
*/
int maxConnections() default PoolFactory.DEFAULT_MAX_CONNECTIONS;
/**
* Configures the minimum number of connections to keep available at all times.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_MIN_CONNECTIONS
*/
int minConnections() default PoolFactory.DEFAULT_MIN_CONNECTIONS;
/**
* If set to true then the created pool can be used by multiple users.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_MULTIUSER_AUTHENTICATION
*/
boolean multiUserAuthentication() default PoolFactory.DEFAULT_MULTIUSER_AUTHENTICATION;
/**
* Configures the name of this GemFire member in the cluster (distributed system).
*
* Default is {@literal SpringBasedCacheClientApplication}.
*/
String name() default ClientCacheConfiguration.DEFAULT_NAME;
/**
* Configures how often to ping servers to verify that they are still alive.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_PING_INTERVAL
*/
long pingInterval() default PoolFactory.DEFAULT_PING_INTERVAL;
/**
* By default {@code prSingleHopEnabled} is {@code true} in which case the client is aware of the location
* of partitions on servers hosting Regions with {@link com.gemstone.gemfire.cache.DataPolicy#PARTITION}.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_PR_SINGLE_HOP_ENABLED
*/
boolean prSingleHopEnabled() default PoolFactory.DEFAULT_PR_SINGLE_HOP_ENABLED;
/**
* 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 com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_READ_TIMEOUT
*/
int readTimeout() default PoolFactory.DEFAULT_READ_TIMEOUT;
/**
* Notifies the server that this durable client is ready to receive updates.
*
* Default is {@code false}.
*/
boolean readyForEvents() default false;
/**
* Configures the number of times to retry a request after timeout/exception.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_RETRY_ATTEMPTS
*/
int retryAttempts() default PoolFactory.DEFAULT_RETRY_ATTEMPTS;
/**
* Configures the group that all servers this pool connects to must belong to.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_SERVER_GROUP
*/
String serverGroup() default PoolFactory.DEFAULT_SERVER_GROUP;
/**
* Configures the GemFire {@link com.gemstone.gemfire.cache.server.CacheServer}s to which
* this cache client will connect.
*/
Server[] servers() default {};
/**
* Configures the socket buffer size for each connection made in this pool.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_SOCKET_BUFFER_SIZE
*/
int socketBufferSize() default PoolFactory.DEFAULT_SOCKET_BUFFER_SIZE;
/**
* Configures how often to send client statistics to the server.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_STATISTIC_INTERVAL
*/
int statisticInterval() default PoolFactory.DEFAULT_STATISTIC_INTERVAL;
/**
* Configures the interval in milliseconds to wait before sending acknowledgements to the cache server
* for events received from the server subscriptions.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_ACK_INTERVAL
*/
int subscriptionAckInterval() default PoolFactory.DEFAULT_SUBSCRIPTION_ACK_INTERVAL;
/**
* If set to true then the created pool will have server-to-client subscriptions enabled.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_ENABLED
*/
boolean subscriptionEnabled() default PoolFactory.DEFAULT_SUBSCRIPTION_ENABLED;
/**
* Configures the messageTrackingTimeout attribute which is the time-to-live period, in milliseconds,
* for subscription events the client has received from the server.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT
*/
int subscriptionMessageTrackingTimeout() default PoolFactory.DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT;
/**
* Configures the redundancy level for this pools server-to-client subscriptions.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_SUBSCRIPTION_REDUNDANCY
*/
int subscriptionRedundancy() default PoolFactory.DEFAULT_SUBSCRIPTION_REDUNDANCY;
/**
* Configures the thread local connections policy for this pool.
*
* @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_THREAD_LOCAL_CONNECTIONS
*/
boolean threadLocalConnections() default PoolFactory.DEFAULT_THREAD_LOCAL_CONNECTIONS;
@interface Locator {
String host() default "localhost";
int port() default GemfireUtils.DEFAULT_LOCATOR_PORT;
}
@interface Server {
String host() default "localhost";
int port() default GemfireUtils.DEFAULT_CACHE_SERVER_PORT;
}
}

View File

@@ -0,0 +1,412 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.context.annotation.Bean;
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.client.ClientCacheFactoryBean;
import org.springframework.data.gemfire.support.ConnectionEndpoint;
/**
* Spring {@link Configuration} class used to configure, construct and initialize
* a GemFire {@link com.gemstone.gemfire.cache.client.ClientCache} instance in a Spring application context.
*
* @author John Blum
* @see org.springframework.context.annotation.Bean
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration
* @see com.gemstone.gemfire.cache.client.ClientCache
* @since 1.0.0
*/
@Configuration
@SuppressWarnings("unused")
public class ClientCacheConfiguration extends AbstractCacheConfiguration {
protected static final boolean DEFAULT_READY_FOR_EVENTS = false;
protected static final String DEFAULT_NAME = "SpringBasedCacheClientApplication";
private boolean readyForEvents = DEFAULT_READY_FOR_EVENTS;
private Boolean keepAlive;
private Boolean multiUserAuthentication;
private Boolean prSingleHopEnabled;
private Boolean subscriptionEnabled;
private Boolean threadLocalConnections;
private Integer durableClientTimeout;
private Integer freeConnectionTimeout;
private Integer loadConditioningInterval;
private Integer maxConnections;
private Integer minConnections;
private Integer readTimeout;
private Integer retryAttempts;
private Integer socketBufferSize;
private Integer statisticsInterval;
private Integer subscriptionAckInterval;
private Integer subscriptionMessageTrackingTimeout;
private Integer subscriptionRedundancy;
private Iterable<ConnectionEndpoint> locators;
private Iterable<ConnectionEndpoint> servers;
private Long idleTimeout;
private Long pingInterval;
private String durableClientId;
private String serverGroup;
@Bean
public ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean gemfireCache = constructCacheFactoryBean();
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());
return gemfireCache;
}
@Override
@SuppressWarnings("unchecked")
protected <T extends CacheFactoryBean> T newCacheFactoryBean() {
return (T) new ClientCacheFactoryBean();
}
/**
* Configures GemFire {@link com.gemstone.gemfire.cache.client.ClientCache} specific settings.
*
* @param importMetadata {@link AnnotationMetadata} containing client cache meta-data used to configure
* the GemFire {@link com.gemstone.gemfire.cache.client.ClientCache}.
* @see org.springframework.core.type.AnnotationMetadata
*/
@Override
protected void configureCache(AnnotationMetadata importMetadata) {
super.configureCache(importMetadata);
if (isClientCacheApplication(importMetadata)) {
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("loadConditionInterval"));
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")));
configureLocatorOrServer(clientCacheApplicationAttributes);
}
}
/* (non-Javadoc) */
void configureLocatorOrServer(Map<String, Object> clientCacheApplicationAttributes) {
AnnotationAttributes[] locators =
(AnnotationAttributes[]) clientCacheApplicationAttributes.get("locators");
List<ConnectionEndpoint> poolLocators = new ArrayList<ConnectionEndpoint>(locators.length);
for (AnnotationAttributes locator : locators) {
poolLocators.add(new ConnectionEndpoint((String) locator.get("host"), (Integer) locator.get("port")));
}
setPoolLocators(poolLocators);
AnnotationAttributes[] servers =
(AnnotationAttributes[]) clientCacheApplicationAttributes.get("servers");
List<ConnectionEndpoint> poolServers = new ArrayList<ConnectionEndpoint>(servers.length);
for (AnnotationAttributes server : servers) {
poolServers.add(new ConnectionEndpoint((String) server.get("host"), (Integer) server.get("port")));
}
setPoolServers(poolServers);
}
@Override
protected Class getAnnotationType() {
return ClientCacheApplication.class;
}
/* (non-Javadoc) */
void setDurableClientId(String durableClientId) {
this.durableClientId = durableClientId;
}
protected String durableClientId() {
return this.durableClientId;
}
/* (non-Javadoc) */
void setDurableClientTimeout(Integer durableClientTimeout) {
this.durableClientTimeout = durableClientTimeout;
}
protected Integer durableClientTimeout() {
return this.durableClientTimeout;
}
/* (non-Javadoc) */
void setFreeConnectionTimeout(Integer freeConnectionTimeout) {
this.freeConnectionTimeout = freeConnectionTimeout;
}
protected Integer freeConnectionTimeout() {
return this.freeConnectionTimeout;
}
/* (non-Javadoc) */
void setIdleTimeout(Long idleTimeout) {
this.idleTimeout = idleTimeout;
}
protected Long idleTimeout() {
return this.idleTimeout;
}
/* (non-Javadoc) */
void setKeepAlive(Boolean keepAlive) {
this.keepAlive = keepAlive;
}
protected Boolean keepAlive() {
return this.keepAlive;
}
/* (non-Javadoc) */
void setLoadConditioningInterval(Integer loadConditioningInterval) {
this.loadConditioningInterval = loadConditioningInterval;
}
protected Integer loadConditioningInterval() {
return this.loadConditioningInterval;
}
/* (non-Javadoc) */
void setMaxConnections(Integer maxConnections) {
this.maxConnections = maxConnections;
}
protected Integer maxConnections() {
return this.maxConnections;
}
/* (non-Javadoc) */
void setMinConnections(Integer minConnections) {
this.minConnections = minConnections;
}
protected Integer minConnections() {
return this.minConnections;
}
/* (non-Javadoc) */
void setMultiUserAuthentication(Boolean multiUserAuthentication) {
this.multiUserAuthentication = multiUserAuthentication;
}
protected Boolean multiUserAuthentication() {
return this.multiUserAuthentication;
}
/* (non-Javadoc) */
void setPingInterval(Long pingInterval) {
this.pingInterval = pingInterval;
}
protected Long pingInterval() {
return this.pingInterval;
}
/* (non-Javadoc) */
void setPoolLocators(Iterable<ConnectionEndpoint> locators) {
this.locators = locators;
}
protected Iterable<ConnectionEndpoint> poolLocators() {
return this.locators;
}
/* (non-Javadoc) */
void setPoolServers(Iterable<ConnectionEndpoint> servers) {
this.servers = servers;
}
protected Iterable<ConnectionEndpoint> poolServers() {
return this.servers;
}
/* (non-Javadoc) */
void setPrSingleHopEnabled(Boolean prSingleHopEnabled) {
this.prSingleHopEnabled = prSingleHopEnabled;
}
protected Boolean prSingleHopEnabled() {
return this.prSingleHopEnabled;
}
/* (non-Javadoc) */
void setReadTimeout(Integer readTimeout) {
this.readTimeout = readTimeout;
}
protected Integer readTimeout() {
return this.readTimeout;
}
/* (non-Javadoc) */
void setReadyForEvents(boolean readyForEvents) {
this.readyForEvents = readyForEvents;
}
protected boolean readyForEvents() {
return this.readyForEvents;
}
/* (non-Javadoc) */
void setRetryAttempts(Integer retryAttempts) {
this.retryAttempts = retryAttempts;
}
protected Integer retryAttempts() {
return this.retryAttempts;
}
/* (non-Javadoc) */
void setServerGroup(String serverGroup) {
this.serverGroup = serverGroup;
}
protected String serverGroup() {
return this.serverGroup;
}
/* (non-Javadoc) */
void setSocketBufferSize(Integer socketBufferSize) {
this.socketBufferSize = socketBufferSize;
}
protected Integer socketBufferSize() {
return this.socketBufferSize;
}
/* (non-Javadoc) */
void setStatisticsInterval(Integer statisticsInterval) {
this.statisticsInterval = statisticsInterval;
}
protected Integer statisticsInterval() {
return this.statisticsInterval;
}
/* (non-Javadoc) */
void setSubscriptionAckInterval(Integer subscriptionAckInterval) {
this.subscriptionAckInterval = subscriptionAckInterval;
}
protected Integer subscriptionAckInterval() {
return this.subscriptionAckInterval;
}
/* (non-Javadoc) */
void setSubscriptionEnabled(Boolean subscriptionEnabled) {
this.subscriptionEnabled = subscriptionEnabled;
}
protected Boolean subscriptionEnabled() {
return this.subscriptionEnabled;
}
/* (non-Javadoc) */
void setSubscriptionMessageTrackingTimeout(Integer subscriptionMessageTrackingTimeout) {
this.subscriptionMessageTrackingTimeout = subscriptionMessageTrackingTimeout;
}
protected Integer subscriptionMessageTrackingTimeout() {
return this.subscriptionMessageTrackingTimeout;
}
/* (non-Javadoc) */
void setSubscriptionRedundancy(Integer subscriptionRedundancy) {
this.subscriptionRedundancy = subscriptionRedundancy;
}
protected Integer subscriptionRedundancy() {
return this.subscriptionRedundancy;
}
/* (non-Javadoc) */
void setThreadLocalConnections(Boolean threadLocalConnections) {
this.threadLocalConnections = threadLocalConnections;
}
protected Boolean threadLocalConnections() {
return this.threadLocalConnections;
}
@Override
public String toString() {
return DEFAULT_NAME;
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Properties;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
/**
* The EmbeddedManagerConfiguration 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.
*
* @author John Blum
* @see EmbeddedServiceConfigurationSupport
* @since 1.9.0
*/
public class EmbeddedLocatorConfiguration extends EmbeddedServiceConfigurationSupport {
@Override
protected Class getAnnotationType() {
return EnableEmbeddedLocator.class;
}
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
Properties gemfireProperties = new Properties();
setProperty(gemfireProperties, "start-locator", annotationAttributes.get("startLocator"));
return gemfireProperties;
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Properties;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
/**
* The EmbeddedManagerConfiguration 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 Manager.
*
* @author John Blum
* @see EmbeddedServiceConfigurationSupport
* @since 1.9.0
*/
public class EmbeddedManagerConfiguration extends EmbeddedServiceConfigurationSupport {
@Override
protected Class getAnnotationType() {
return EnableEmbeddedManager.class;
}
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
Properties gemfireProperties = new Properties();
boolean jmxManager = Boolean.valueOf(String.valueOf(annotationAttributes.get("jmxManager")));
if (jmxManager) {
setProperty(gemfireProperties, "jmx-manager", Boolean.TRUE.toString());
setProperty(gemfireProperties, "jmx-manager-access-file", annotationAttributes.get("jmxManagerAccessFile"));
setProperty(gemfireProperties, "jmx-manager-bind-address", annotationAttributes.get("jmxManagerBindAddress"));
setProperty(gemfireProperties, "jmx-manager-hostname-for-clients", annotationAttributes.get("jmxManagerHostnameForClients"));
setProperty(gemfireProperties, "jmx-manager-password-file", annotationAttributes.get("jmxManagerPasswordFile"));
setProperty(gemfireProperties, "jmx-manager-port", annotationAttributes.get("jmxManagerPort"));
setProperty(gemfireProperties, "jmx-manager-start", annotationAttributes.get("jmxManagerStart"));
setProperty(gemfireProperties, "jmx-manager-update-rate", annotationAttributes.get("jmxManagerUpdateRate"));
boolean jmxManagerSslEnabled = Boolean.valueOf(String.valueOf(annotationAttributes.get("jmxManagerSslEnabled")));
if (jmxManagerSslEnabled) {
setProperty(gemfireProperties, "jmx-manager-ssl-enabled", Boolean.TRUE.toString());
setProperty(gemfireProperties, "jmx-manager-ssl-ciphers", annotationAttributes.get("jmxManagerSslCiphers"));
setProperty(gemfireProperties, "jmx-manager-ssl-protocols", annotationAttributes.get("jmxManagerSslProtocols"));
setProperty(gemfireProperties, "jmx-manager-ssl-require-authentication", annotationAttributes.get("jmxManagerSslRequireAuthentication"));
}
}
return gemfireProperties;
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
/**
* The EnableEmbeddedLocator annotation marks a Spring {@link org.springframework.context.annotation.Configuration}
* class to embed a GemFire Locator service in the GemFire server-side data member node.
*
* @author John Blum
* @see org.springframework.data.gemfire.config.annotation.EmbeddedLocatorConfiguration
* @since 1.9.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EmbeddedLocatorConfiguration.class)
@SuppressWarnings("unused")
public @interface EnableEmbeddedLocator {
/**
* If set, automatically starts a Locator in the current process when the member connects to the distributed system
* and stops the Locator when the member disconnects.
* To use, specify the Locator with an optional address or host specification and a required port number, in one of
* these formats:
*
* start-locator=address[port1]
*
* start-locator=port1
*
* If you only specify the port, the address assigned to the member is used for the Locator.
* If not already there, this locator is automatically added to the list of Locators in this
* set of GemFire Properties.
*
* Defaults to {@literal 10334} (The default GemFire Locator port).
*/
String startLocator() default "localhost[10334]";
}

View File

@@ -0,0 +1,156 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
/**
* The EnableEmbeddedLocator annotation marks a Spring {@link org.springframework.context.annotation.Configuration}
* class to embed a GemFire Manager service in the GemFire server-side data member node.
*
* @author John Blum
* @see org.springframework.data.gemfire.config.annotation.EmbeddedManagerConfiguration
* @since 1.9.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EmbeddedManagerConfiguration.class)
@SuppressWarnings("unused")
public @interface EnableEmbeddedManager {
/**
* If {@code true} then this member is willing to be a JMX Manager. All the other JMX Manager properties will be
* used when it does become a manager. If this property is {@code false} then all other jmx-manager-* properties
* are ignored.
*
* Defaults to {@code true}.
*/
boolean jmxManager() default true;
/**
* By default, the JMX Manager will allow full access to all mbeans by any client. If this property is set to
* the name of a file then it can restrict clients to only being able to read MBeans; they will not be able
* to modify MBeans. The access level can be configured differently in this file for each user name defined
* in the password file. For more information about the format of this file see Oracle's documentation
* of the {@code com.sun.management.jmxremote.access.file} System property. Ignored if {@literal jmx-manager}
* is false or if {@literal jmx-manager-port} is zero.
*/
String jmxManagerAccessFile() default "";
/**
* By default, the JMX Manager (when configured with a port) will listen on all the local host's addresses.
* You can use this property to configure what IP address or host name the JMX Manager will listen on for
* non-HTTP connections. Ignored if JMX Manager is {@code false} or {@literal jmx-manager-port} is zero.
*
* Defaults to {@literal localhost}.
*/
String jmxManagerBindAddress() default "localhost";
/**
* Lets you control what hostname will be given to clients that ask the Locator for the location of a JMX Manager.
* By default, the IP address that the JMX Manager reports is used. But for clients on a different network
* this property allows you to configure a different hostname that will be given to clients. Ignored if
* {@literal jmx-manager} is {@code false} or {@literal jmx-manager-port} is zero.
*
* Defaults to {@literal localhost}.
*/
String jmxManagerHostnameForClients() default "localhost";
/**
* By default, the JMX Manager will allow clients without credentials to connect. If this property is set to
* the name of a file then only clients that connect with credentials that match an entry in this file will
* be allowed. Most JVMs require that the file is only readable by the owner. For more information about the
* format of this file see Oracle's documentation of the {@literal com.sun.management.jmxremote.password.file}
* System property. Ignored if {@literal jmx-manager} is {@code false} or {@literal jmx-manager-port} is zero.
*/
String jmxManagerPasswordFile() default "";
/**
* The port this JMX Manager will listen to for client connections. If this property is set to zero then GemFire
* will not allow remote client connections but you can alternatively use the standard System properties supported
* by the JVM for configuring access from remote JMX clients. Ignored if {@literal jmx-manager} is {@code false}.
*
* Defaults to {@literal 1099}.
*/
int jmxManagerPort() default 1099;
/**
* Enables or disables SSL for connections to the JMX Manager. If {@code true} and {@literal jmx-manager-port}
* is not zero, then the JMX Manager will only accept SSL connections. If this property is not set, then GemFire
* uses the value of {@literal cluster-ssl-enabled} to determine whether JMX connections should use SSL.
*
* Defaults to {@code false}.
*/
boolean jmxManagerSslEnabled() default false;
/**
* A space-separated list of the valid SSL ciphers for JMX Manager connections. A setting of 'any' uses any ciphers
* that are enabled by default in the configured JSSE provider. If this property is not set, then GemFire uses
* the value of {@literal cluster-ssl-ciphers} to determine which SSL ciphers are used for JMX connections.
*
* Defaults to {@literal any}.
*/
String jmxManagerSslCiphers() default "any";
/**
* A space-separated list of the valid SSL protocols for JMX Manager connections. A setting of 'any' uses any
* protocol that is enabled by default in the configured JSSE provider. If this property is not set, then GemFire
* uses the value of {@literal cluster-ssl-protocols} to determine which SSL protocols are used for JMX connections.
*
* Defaults to {@literal any}.
*/
String jmxManagerSslProtocols() default "any";
/**
* Boolean indicating whether to require authentication for JMX Manager connections. If this property is not set,
* then GemFire uses the value of {@literal cluster-ssl-require-authentication} to determine whether JMX connections
* require authentication.
*
* Defaults to {@code true}.
*/
boolean jmxManagerSslRequireAuthentication() default true;
/**
* If true then this member will start a JMX Manager when it creates a cache. Management tools like Gfsh can be
* configured to connect to the JMX Manager. In most cases you should not set this because a JMX Manager will
* automatically be started when needed on a member that sets {@literal jmx-manager} to {@code true}. Ignored if
* {@literal jmx-manager} is {@code false}.
*
* Defaults to {@code false}.
*/
boolean jmxManagerStart() default false;
/**
* The rate, in milliseconds, at which this member will push updates to any JMX Managers. Currently this value
* should be greater than or equal to the {@literal statistic-sample-rate}. Setting this value too high will
* cause stale values to be seen by Gfsh and GemFire Pulse.
*
* Defaults to {@code 2000}.
*/
int jmxManagerUpdateRate() default 2000;
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
/**
* The EnableMemcachedServer annotation marks a Spring {@link org.springframework.context.annotation.Configuration}
* class to embed the Gemcached service in the GemFire server-side data member node.
*
* The Gemcached service implements the Memcached server protocol enabling Memcached clients to connect and speak
* to Pivotal GemFire or Apache Geode.
*
* @author John Blum
* @see org.springframework.data.gemfire.config.annotation.MemcachedServerConfiguration
* @since 1.9.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(MemcachedServerConfiguration.class)
@SuppressWarnings("unused")
public @interface EnableMemcachedServer {
/**
* If specified and is non-zero, sets the port number for an embedded Gemcached server
* and starts the Gemcached server.
*
* Default to {@literal 11211}.
*/
int port() default 11211;
/**
* Sets the protocol used by an embedded Gemcached server. Valid values are BINARY and ASCII.
* If you omit this property, the ASCII protocol is used.
*
* Default to {@link MemcachedProtocol#ASCII}.
*/
MemcachedProtocol protocol() default MemcachedProtocol.ASCII;
/**
* Valid values for the Memcached Network Protocol on-the-wire transport.
*/
enum MemcachedProtocol {
ASCII,
BINARY
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The EnablePdx class...
*
* @author John Blum
* @since 1.0.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SuppressWarnings("unused")
public @interface EnablePdx {
String diskStoreName();
boolean ignoreUnreadFields() default false;
boolean persistent() default false;
boolean readSerialized() default false;
String serializerBeanName() default "";
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Properties;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
/**
* 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.
*
* @author John Blum
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
*/
public class MemcachedServerConfiguration extends EmbeddedServiceConfigurationSupport {
@Override
protected Class getAnnotationType() {
return EnableMemcachedServer.class;
}
@Override
protected Properties toGemFireProperties(Map<String, Object> annotationAttributes) {
Properties gemfireProperties = new Properties();
setProperty(gemfireProperties, "memcached-port", annotationAttributes.get("port"));
setProperty(gemfireProperties, "memcached-protocol", annotationAttributes.get("protocol"));
return gemfireProperties;
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.gemstone.gemfire.cache.control.ResourceManager;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* The PeerCacheApplication annotation enables an embedded GemFire peer {@link com.gemstone.gemfire.cache.Cache}
* instance in a Spring Data GemFire based application.
*
* @author John Blum
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.PeerCacheConfiguration
* @see com.gemstone.gemfire.cache.control.ResourceManager
* @since 1.9.0
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@Import(PeerCacheConfiguration.class)
@SuppressWarnings("unused")
public @interface PeerCacheApplication {
/**
* Indicates whether the "copy on read" is enabled for this cache.
*
* Default is {@code false}.
*/
boolean copyOnRead() default false;
/**
* Configures the percentage of heap at or above which the cache is considered in danger of becoming inoperable.
*
* @see com.gemstone.gemfire.cache.control.ResourceManager#DEFAULT_CRITICAL_HEAP_PERCENTAGE
*/
float criticalHeapPercentage() default ResourceManager.DEFAULT_CRITICAL_HEAP_PERCENTAGE;
/**
* By default, a GemFire member (both locators and servers) will attempt to reconnect and reinitialize the cache
* 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 {@code false}.
*/
boolean enableAutoReconnect() default false;
/**
* Configures the percentage of heap at or above which the eviction should begin on Regions configured
* for HeapLRU eviction.
*
* @see com.gemstone.gemfire.cache.control.ResourceManager#DEFAULT_EVICTION_HEAP_PERCENTAGE
*/
float evictionHeapPercentage() default ResourceManager.DEFAULT_EVICTION_HEAP_PERCENTAGE;
/**
* Configures the list of GemFire Locators defining the cluster to which this GemFire cache data node
* should connect.
*/
String locators() default "";
/**
* Configures the length, in seconds, of distributed lock leases obtained by this cache.
*
* Default is {@literal 120} seconds.
*/
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.
*/
int lockTimeout() default 60;
/**
* Configures the log level used to output log messages at GemFire cache runtime.
*
* Default is {@literal config}.
*/
String logLevel() default PeerCacheConfiguration.DEFAULT_LOG_LEVEL;
/**
* 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.
*/
int messageSyncInterval() default 1;
/**
* Configures the name of this GemFire member in the cluster (distributed system).
*
* Default is {@literal SpringBasedPeerCacheApplication}.
*/
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.
*/
int searchTimeout() default 300;
/**
* Configures whether this GemFire cache member node would pull it's configuration meta-data
* from the cluster-based Cluster Configuration service.
*
* Default is {@code false}.
*/
boolean useClusterConfiguration() default false;
}

View File

@@ -0,0 +1,169 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.CacheFactoryBean;
/**
* Spring {@link Configuration} class used to configure, construct and initialize
* a GemFire {@link com.gemstone.gemfire.cache.Cache} instance in a Spring application context.
*
* @author John Blum
* @see org.springframework.context.annotation.Bean
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration
* @see com.gemstone.gemfire.cache.Cache
* @since 1.9.0
*/
@Configuration
@SuppressWarnings("unused")
public class PeerCacheConfiguration extends AbstractCacheConfiguration {
protected static final boolean DEFAULT_ENABLE_AUTO_RECONNECT = false;
protected static final boolean DEFAULT_USE_CLUSTER_CONFIGURATION = false;
protected static final String DEFAULT_NAME = "SpringBasedPeerCacheApplication";
private boolean enableAutoReconnect = DEFAULT_ENABLE_AUTO_RECONNECT;
private boolean useClusterConfiguration = DEFAULT_USE_CLUSTER_CONFIGURATION;
private Integer lockLease;
private Integer lockTimeout;
private Integer messageSyncInterval;
private Integer searchTimeout;
@Bean
public CacheFactoryBean gemfireCache() {
CacheFactoryBean gemfireCache = constructCacheFactoryBean();
gemfireCache.setEnableAutoReconnect(enableAutoReconnect());
gemfireCache.setLockLease(lockLease());
gemfireCache.setLockTimeout(lockTimeout());
gemfireCache.setMessageSyncInterval(messageSyncInterval());
gemfireCache.setSearchTimeout(searchTimeout());
gemfireCache.setUseBeanFactoryLocator(useBeanFactoryLocator());
gemfireCache.setUseClusterConfiguration(useClusterConfiguration());
return gemfireCache;
}
@Override
@SuppressWarnings("unchecked")
protected <T extends CacheFactoryBean> T newCacheFactoryBean() {
return (T) new CacheFactoryBean();
}
/**
* Configures GemFire peer {@link com.gemstone.gemfire.cache.Cache} specific settings.
*
* @param importMetadata {@link AnnotationMetadata} containing peer cache meta-data used to configure
* the GemFire peer {@link com.gemstone.gemfire.cache.Cache}.
* @see org.springframework.core.type.AnnotationMetadata
*/
@Override
protected void configureCache(AnnotationMetadata importMetadata) {
super.configureCache(importMetadata);
if (isPeerCacheApplication(importMetadata) || isCacheServerApplication(importMetadata)) {
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")));
String locators = (String) peerCacheApplicationAttributes.get("locators");
if (hasValue(locators)) {
setLocators(locators);
}
}
}
@Override
protected Class getAnnotationType() {
return PeerCacheApplication.class;
}
/* (non-Javadoc) */
void setEnableAutoReconnect(boolean enableAutoReconnect) {
this.enableAutoReconnect = enableAutoReconnect;
}
protected boolean enableAutoReconnect() {
return this.enableAutoReconnect;
}
/* (non-Javadoc) */
void setLockLease(Integer lockLease) {
this.lockLease = lockLease;
}
protected Integer lockLease() {
return this.lockLease;
}
/* (non-Javadoc) */
void setLockTimeout(Integer lockTimeout) {
this.lockTimeout = lockTimeout;
}
protected Integer lockTimeout() {
return this.lockTimeout;
}
/* (non-Javadoc) */
void setMessageSyncInterval(Integer messageSyncInterval) {
this.messageSyncInterval = messageSyncInterval;
}
protected Integer messageSyncInterval() {
return this.messageSyncInterval;
}
/* (non-Javadoc) */
void setSearchTimeout(Integer searchTimeout) {
this.searchTimeout = searchTimeout;
}
protected Integer searchTimeout() {
return this.searchTimeout;
}
/* (non-Javadoc) */
void setUseClusterConfiguration(boolean useClusterConfiguration) {
this.useClusterConfiguration = useClusterConfiguration;
}
protected boolean useClusterConfiguration() {
return this.useClusterConfiguration;
}
@Override
public String toString() {
return DEFAULT_NAME;
}
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation.support;
import java.util.Map;
import java.util.Properties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanPostProcessor;
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.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.util.CollectionUtils;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* The EmbeddedServiceConfigurationSupport class is an abstract base class supporting the configuration
* of Pivotal GemFire and Apache Geode embedded services.
*
* @author John Blum
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar
* @since 1.9.0
*/
public abstract class EmbeddedServiceConfigurationSupport implements ImportBeanDefinitionRegistrar {
/* (non-Javadoc) */
protected static Properties setProperty(Properties properties, String key, Object value) {
if (value != null) {
setProperty(properties, key, value.toString());
}
return properties;
}
/* (non-Javadoc) */
protected static Properties setProperty(Properties properties, String key, String value) {
Assert.notNull(properties, "Properties must not be null");
Assert.hasText(key, "Key must not be null or empty");
if (StringUtils.hasText(value)) {
properties.setProperty(key, value);
}
return properties;
}
/* (non-Javadoc) */
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (importingClassMetadata.hasAnnotation(getAnnotationTypeName())) {
Map<String, Object> annotationAttributes =
importingClassMetadata.getAnnotationAttributes(getAnnotationTypeName());
Properties customizedGemFireProperties = toGemFireProperties(annotationAttributes);
if (!CollectionUtils.isEmpty(customizedGemFireProperties)) {
registerGemFirePropertiesBeanPostProcessor(registry, customizedGemFireProperties);
}
}
}
/* (non-Javadoc) */
protected String getAnnotationTypeName() {
return getAnnotationType().getName();
}
/* (non-Javadoc) */
protected String getAnnotationTypeSimpleName() {
return getAnnotationType().getSimpleName();
}
/* (non-Javadoc) */
protected abstract Class getAnnotationType();
/* (non-Javadoc) */
protected String getBeanName() {
return String.format("%1$s.%2$s", getClass().getName(), getAnnotationTypeSimpleName());
}
/* (non-Javadoc) */
protected BeanDefinitionHolder newBeanDefinitionHolder(BeanDefinitionBuilder builder) {
return new BeanDefinitionHolder(builder.getBeanDefinition(), getBeanName());
}
/* (non-Javadoc) */
protected abstract Properties toGemFireProperties(Map<String, Object> annotationAttributes);
/* (non-Javadoc) */
protected void registerGemFirePropertiesBeanPostProcessor(BeanDefinitionRegistry registry,
Properties customizedGemFireProperties) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
GemFirePropertiesBeanPostProcessor.class);
builder.addConstructorArgValue(customizedGemFireProperties);
BeanDefinitionReaderUtils.registerBeanDefinition(newBeanDefinitionHolder(builder), registry);
}
/**
* Spring {@link BeanPostProcessor} used to post process before initialization in GemFire System properties
* Spring bean defined in the application context.
*
* @see org.springframework.beans.factory.config.BeanPostProcessor
*/
protected static class GemFirePropertiesBeanPostProcessor implements BeanPostProcessor {
static final String GEMFIRE_PROPERTIES_BEAN_NAME = "gemfireProperties";
private final Properties gemfireProperties;
protected GemFirePropertiesBeanPostProcessor(Properties gemfireProperties) {
Assert.notEmpty(gemfireProperties, "GemFire Properties must not be null or empty");
this.gemfireProperties = gemfireProperties;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof Properties && GEMFIRE_PROPERTIES_BEAN_NAME.equals(beanName)) {
Properties gemfirePropertiesBean = (Properties) bean;
gemfirePropertiesBean.putAll(gemfireProperties);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
}

View File

@@ -19,6 +19,12 @@ import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.InterestRegistrationListener;
import com.gemstone.gemfire.cache.server.CacheServer;
import com.gemstone.gemfire.cache.server.ClientSubscriptionConfig;
import com.gemstone.gemfire.cache.server.ServerLoadProbe;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
@@ -27,12 +33,6 @@ import org.springframework.context.SmartLifecycle;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.InterestRegistrationListener;
import com.gemstone.gemfire.cache.server.CacheServer;
import com.gemstone.gemfire.cache.server.ClientSubscriptionConfig;
import com.gemstone.gemfire.cache.server.ServerLoadProbe;
/**
* FactoryBean for easy creation and configuration of GemFire {@link CacheServer} instances.
*