diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/AbstractCacheConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/AbstractCacheConfiguration.java index b8bf3ff3..b85b619c 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/AbstractCacheConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/AbstractCacheConfiguration.java @@ -19,13 +19,13 @@ package org.springframework.data.gemfire.config.annotation; import static org.springframework.data.gemfire.CacheFactoryBean.DynamicRegionSupport; import static org.springframework.data.gemfire.CacheFactoryBean.JndiDataSource; +import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeList; +import static org.springframework.data.gemfire.util.SpringUtils.defaultIfNull; import java.lang.annotation.Annotation; -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; @@ -46,12 +46,13 @@ 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 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, Annotation * {@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}. + * This class encapsulates 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 @@ -59,7 +60,9 @@ import org.springframework.util.StringUtils; * @see org.springframework.beans.factory.BeanFactoryAware * @see org.springframework.context.annotation.Bean * @see org.springframework.context.annotation.ImportAware + * @see org.springframework.core.io.Resource * @see org.springframework.core.type.AnnotationMetadata + * @see org.springframework.data.gemfire.CacheFactoryBean * @since 1.9.0 */ @SuppressWarnings("unused") @@ -112,44 +115,6 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be private TransactionWriter transactionWriter; - /** - * Returns the given {@link List} if not null or an empty {@link List}. - * - * @param 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 List nullSafeList(List list) { - return (list != null ? list : Collections.emptyList()); - } - - /** - * Returns the given {@link Set} if not null or an empty {@link Set}. - * - * @param 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 Set nullSafeSet(Set set) { - return (set != null ? set : Collections.emptySet()); - } - - /** - * Returns the given {@code value} if not null or the {@code defaultValue}. - * - * @param 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 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}. @@ -216,9 +181,8 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be return gemfireProperties.build(); } - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.BeanClassLoaderAware + /** + * {@inheritDoc} */ @Override public void setBeanClassLoader(ClassLoader beanClassLoader) { @@ -236,9 +200,8 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be return beanClassLoader; } - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.BeanFactoryAware + /** + * {@inheritDoc} */ @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { @@ -257,10 +220,8 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be return this.beanFactory; } - /* - * (non-Javadoc) - * @see org.springframework.context.annotation.ImportAware - * @see org.springframework.core.type.AnnotationMetadata + /** + * {@inheritDoc} */ @Override public void setImportMetadata(AnnotationMetadata importMetadata) { @@ -601,7 +562,7 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be } protected String logLevel() { - return nullSafeValue(this.logLevel, DEFAULT_LOG_LEVEL); + return defaultIfNull(this.logLevel, DEFAULT_LOG_LEVEL); } void setMcastPort(Integer mcastPort) { @@ -706,6 +667,9 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be customGemFireProperties.add(gemfireProperties); } + /** + * {@inheritDoc} + */ @Override public String toString() { return DEFAULT_NAME; diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/AddCacheServerConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/AddCacheServerConfiguration.java index 3508017e..d38efa0d 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/AddCacheServerConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/AddCacheServerConfiguration.java @@ -28,9 +28,9 @@ import org.springframework.data.gemfire.config.xml.GemfireConstants; import org.springframework.data.gemfire.server.CacheServerFactoryBean; /** - * The AddCacheServerConfiguration class is a Spring {@link ImportBeanDefinitionRegistrar} that registers + * The {@link AddCacheServerConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} that registers * a {@link CacheServerFactoryBean} definition for the {@link com.gemstone.gemfire.cache.server.CacheServer} - * configuration meta-data. + * configuration meta-data defined in {@link EnableCacheServer}. * * @author John Blum * @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar @@ -39,9 +39,8 @@ import org.springframework.data.gemfire.server.CacheServerFactoryBean; */ public class AddCacheServerConfiguration implements ImportBeanDefinitionRegistrar { - /* - * (non-Javadoc) - * @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry) + /** + * {@inheritDoc} */ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { @@ -49,7 +48,7 @@ public class AddCacheServerConfiguration implements ImportBeanDefinitionRegistra Map enableCacheServerAttributes = importingClassMetadata.getAnnotationAttributes( EnableCacheServer.class.getName()); - addCacheServerFactoryBeanDefinition(enableCacheServerAttributes, registry); + registerCacheServerFactoryBeanDefinition(enableCacheServerAttributes, registry); } } @@ -57,33 +56,33 @@ public class AddCacheServerConfiguration implements ImportBeanDefinitionRegistra * Registers a {@link CacheServerFactoryBean} bean definition for the given {@link EnableCacheServer} annotation * configuration meta-data. * - * @param annotationAttributes attributes for the {@link EnableCacheServer} annotation. + * @param enableCacheServerAttributes attributes for the {@link EnableCacheServer} annotation. * @param registry {@link BeanDefinitionRegistry} used to register the {@link CacheServerFactoryBean} * bean definition. * @see org.springframework.beans.factory.support.BeanDefinitionBuilder * @see org.springframework.beans.factory.support.BeanDefinitionRegistry * @see org.springframework.data.gemfire.server.CacheServerFactoryBean */ - protected void addCacheServerFactoryBeanDefinition(Map annotationAttributes, + protected void registerCacheServerFactoryBeanDefinition(Map enableCacheServerAttributes, BeanDefinitionRegistry registry) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CacheServerFactoryBean.class); builder.addPropertyReference("cache", GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME); - builder.addPropertyValue("autoStartup", annotationAttributes.get("autoStartup")); - builder.addPropertyValue("bindAddress", annotationAttributes.get("bindAddress")); - builder.addPropertyValue("hostNameForClients", annotationAttributes.get("hostnameForClients")); - builder.addPropertyValue("loadPollInterval", annotationAttributes.get("loadPollInterval")); - builder.addPropertyValue("maxConnections", annotationAttributes.get("maxConnections")); - builder.addPropertyValue("maxMessageCount", annotationAttributes.get("maxMessageCount")); - builder.addPropertyValue("maxThreads", annotationAttributes.get("maxThreads")); - builder.addPropertyValue("maxTimeBetweenPings", annotationAttributes.get("maxTimeBetweenPings")); - builder.addPropertyValue("messageTimeToLive", annotationAttributes.get("messageTimeToLive")); - builder.addPropertyValue("port", annotationAttributes.get("port")); - builder.addPropertyValue("socketBufferSize", annotationAttributes.get("socketBufferSize")); - builder.addPropertyValue("subscriptionCapacity", annotationAttributes.get("subscriptionCapacity")); - builder.addPropertyValue("subscriptionDiskStore", annotationAttributes.get("subscriptionDiskStoreName")); - builder.addPropertyValue("subscriptionEvictionPolicy", annotationAttributes.get("subscriptionEvictionPolicy")); + builder.addPropertyValue("autoStartup", enableCacheServerAttributes.get("autoStartup")); + builder.addPropertyValue("bindAddress", enableCacheServerAttributes.get("bindAddress")); + builder.addPropertyValue("hostNameForClients", enableCacheServerAttributes.get("hostnameForClients")); + builder.addPropertyValue("loadPollInterval", enableCacheServerAttributes.get("loadPollInterval")); + builder.addPropertyValue("maxConnections", enableCacheServerAttributes.get("maxConnections")); + builder.addPropertyValue("maxMessageCount", enableCacheServerAttributes.get("maxMessageCount")); + builder.addPropertyValue("maxThreads", enableCacheServerAttributes.get("maxThreads")); + builder.addPropertyValue("maxTimeBetweenPings", enableCacheServerAttributes.get("maxTimeBetweenPings")); + builder.addPropertyValue("messageTimeToLive", enableCacheServerAttributes.get("messageTimeToLive")); + builder.addPropertyValue("port", enableCacheServerAttributes.get("port")); + builder.addPropertyValue("socketBufferSize", enableCacheServerAttributes.get("socketBufferSize")); + builder.addPropertyValue("subscriptionCapacity", enableCacheServerAttributes.get("subscriptionCapacity")); + builder.addPropertyValue("subscriptionDiskStore", enableCacheServerAttributes.get("subscriptionDiskStoreName")); + builder.addPropertyValue("subscriptionEvictionPolicy", enableCacheServerAttributes.get("subscriptionEvictionPolicy")); BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), registry); } diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/AddCacheServersConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/AddCacheServersConfiguration.java index 61b8d557..7f81437e 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/AddCacheServersConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/AddCacheServersConfiguration.java @@ -24,20 +24,20 @@ import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; /** - * The AddCacheServersConfiguration class registers {@link org.springframework.data.gemfire.server.CacheServerFactoryBean} + * The {@link AddCacheServersConfiguration} class registers {@link org.springframework.data.gemfire.server.CacheServerFactoryBean} * bean definitions for all {@link EnableCacheServer} annotation configuration meta-data defined in - * the {@link EnableCacheServers} annotation on the GemFire cache application class. + * the {@link EnableCacheServers} annotation on a GemFire peer cache application class. * * @author John Blum * @see org.springframework.data.gemfire.config.annotation.AddCacheServerConfiguration + * @see org.springframework.data.gemfire.config.annotation.EnableCacheServer * @see org.springframework.data.gemfire.config.annotation.EnableCacheServers * @since 1.9.0 */ public class AddCacheServersConfiguration extends AddCacheServerConfiguration { - /* - * (non-Javadoc) - * @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry) + /** + * {@inheritDoc} */ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { @@ -49,7 +49,7 @@ public class AddCacheServersConfiguration extends AddCacheServerConfiguration { (AnnotationAttributes[]) enableCacheServersAttributes.get("servers"); for (AnnotationAttributes enableCacheServerAttributes : serversAttributes) { - addCacheServerFactoryBeanDefinition(enableCacheServerAttributes, registry); + registerCacheServerFactoryBeanDefinition(enableCacheServerAttributes, registry); } } } diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/AddPoolConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/AddPoolConfiguration.java new file mode 100644 index 00000000..ec9477b8 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/AddPoolConfiguration.java @@ -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.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.data.gemfire.GemfireUtils; +import org.springframework.data.gemfire.client.PoolFactoryBean; +import org.springframework.data.gemfire.support.ConnectionEndpoint; +import org.springframework.data.gemfire.support.ConnectionEndpointList; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * The {@link AddCacheServerConfiguration} class is a Spring {@link ImportBeanDefinitionRegistrar} that registers + * a {@link PoolFactoryBean} definition for the {@link com.gemstone.gemfire.cache.client.Pool} + * configuration meta-data defined in {@link EnablePool}. + * + * @author John Blum + * @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar + * @see org.springframework.data.gemfire.config.annotation.EnablePool + * @since 1.9.0 + */ +public class AddPoolConfiguration implements ImportBeanDefinitionRegistrar { + + /** + * {@inheritDoc} + */ + @Override + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { + if (importingClassMetadata.hasAnnotation(EnablePool.class.getName())) { + Map enablePoolAttributes = importingClassMetadata.getAnnotationAttributes( + EnablePool.class.getName()); + + registerPoolFactoryBeanDefinition(enablePoolAttributes, registry); + } + } + + /** + * Registers a {@link PoolFactoryBean} definition in the Spring application context configured with + * the {@link EnablePool} annotation meta-data. + * + * @param enablePoolAttributes {@link EnablePool} annotation attributes. + * @param registry Spring {@link BeanDefinitionRegistry used to register the {@link PoolFactoryBean} definition. + * @see org.springframework.beans.factory.support.BeanDefinitionRegistry + * @see org.springframework.data.gemfire.client.PoolFactoryBean + * @see org.springframework.data.gemfire.config.annotation.EnablePool + * @see java.util.Map + */ + protected void registerPoolFactoryBeanDefinition(Map enablePoolAttributes, + BeanDefinitionRegistry registry) { + + String poolName = getAndValidatePoolName(enablePoolAttributes); + + BeanDefinitionBuilder poolFactoryBean = BeanDefinitionBuilder.genericBeanDefinition(PoolFactoryBean.class); + + poolFactoryBean.addPropertyValue("freeConnectionTimeout", enablePoolAttributes.get("freeConnectionTimeout")); + poolFactoryBean.addPropertyValue("idleTimeout", enablePoolAttributes.get("idleTimeout")); + poolFactoryBean.addPropertyValue("loadConditioningInterval", enablePoolAttributes.get("loadConditioningInterval")); + poolFactoryBean.addPropertyValue("maxConnections", enablePoolAttributes.get("maxConnections")); + poolFactoryBean.addPropertyValue("minConnections", enablePoolAttributes.get("minConnections")); + poolFactoryBean.addPropertyValue("multiUserAuthentication", enablePoolAttributes.get("multiUserAuthentication")); + poolFactoryBean.addPropertyValue("pingInterval", enablePoolAttributes.get("pingInterval")); + poolFactoryBean.addPropertyValue("prSingleHopEnabled", enablePoolAttributes.get("prSingleHopEnabled")); + poolFactoryBean.addPropertyValue("readTimeout", enablePoolAttributes.get("readTimeout")); + poolFactoryBean.addPropertyValue("retryAttempts", enablePoolAttributes.get("retryAttempts")); + poolFactoryBean.addPropertyValue("serverGroup", enablePoolAttributes.get("serverGroup")); + poolFactoryBean.addPropertyValue("socketBufferSize", enablePoolAttributes.get("socketBufferSize")); + poolFactoryBean.addPropertyValue("statisticInterval", enablePoolAttributes.get("statisticInterval")); + poolFactoryBean.addPropertyValue("subscriptionAckInterval", enablePoolAttributes.get("subscriptionAckInterval")); + poolFactoryBean.addPropertyValue("subscriptionEnabled", enablePoolAttributes.get("subscriptionEnabled")); + poolFactoryBean.addPropertyValue("subscriptionMessageTrackingTimeout", enablePoolAttributes.get("subscriptionMessageTrackingTimeout")); + poolFactoryBean.addPropertyValue("subscriptionRedundancy", enablePoolAttributes.get("subscriptionRedundancy")); + poolFactoryBean.addPropertyValue("threadLocalConnections", enablePoolAttributes.get("threadLocalConnections")); + + configurePoolConnections(enablePoolAttributes, poolFactoryBean); + + registry.registerBeanDefinition(poolName, poolFactoryBean.getBeanDefinition()); + } + + protected String getAndValidatePoolName(Map enablePoolAttributes) { + String poolName = (String) enablePoolAttributes.get("name"); + Assert.hasText(poolName, "Pool name must be specified"); + return poolName; + } + + /** + * Uses the list of GemFire Locator and Server connection endpoint definitions and meta-data to configure + * the GemFire client {@link com.gemstone.gemfire.cache.client.Pool} used to communicate with the servers + * in the GemFire cluster. + * + * @param enablePoolAttributes {@link EnablePool} annotation containing + * {@link com.gemstone.gemfire.cache.client.Pool} Locator/Server connection endpoint meta-data. + * @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication + * @see java.util.Map + */ + protected BeanDefinitionBuilder configurePoolConnections(Map enablePoolAttributes, + BeanDefinitionBuilder poolFactoryBean) { + + configureLocators(enablePoolAttributes, poolFactoryBean); + configureServers(enablePoolAttributes, poolFactoryBean); + + return poolFactoryBean; + } + + protected BeanDefinitionBuilder configureLocators(Map enablePoolAttributes, + BeanDefinitionBuilder poolFactoryBean) { + + poolFactoryBean.addPropertyValue("locators", parseConnectionEndpoints(enablePoolAttributes, + "locators", "locatorsString", GemfireUtils.DEFAULT_LOCATOR_PORT)); + + return poolFactoryBean; + } + + protected BeanDefinitionBuilder configureServers(Map enablePoolAttributes, + BeanDefinitionBuilder poolFactoryBean) { + + poolFactoryBean.addPropertyValue("servers", parseConnectionEndpoints(enablePoolAttributes, + "servers", "serversString", GemfireUtils.DEFAULT_CACHE_SERVER_PORT)); + + return poolFactoryBean; + } + + protected ConnectionEndpointList parseConnectionEndpoints(Map enablePoolAttributes, + String arrayAttributeName, String stringAttributeName, int defaultPort) { + + ConnectionEndpointList connectionEndpoints = new ConnectionEndpointList(); + + AnnotationAttributes[] connectionEndpointsMetaData = + (AnnotationAttributes[]) enablePoolAttributes.get(arrayAttributeName); + + for (AnnotationAttributes annotationAttributes : connectionEndpointsMetaData) { + connectionEndpoints.add(newConnectionEndpoint((String) annotationAttributes.get("host"), + (Integer) annotationAttributes.get("port"))); + } + + String hostsPorts = (String) enablePoolAttributes.get(stringAttributeName); + + if (StringUtils.hasText(hostsPorts)) { + connectionEndpoints.add(ConnectionEndpointList.parse(defaultPort, hostsPorts.split(","))); + } + + return connectionEndpoints; + } + + protected ConnectionEndpoint newConnectionEndpoint(String host, Integer port) { + return new ConnectionEndpoint(host, port); + } +} diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/AddPoolsConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/AddPoolsConfiguration.java new file mode 100644 index 00000000..c4523ded --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/AddPoolsConfiguration.java @@ -0,0 +1,55 @@ +/* + * 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.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.type.AnnotationMetadata; + +/** + * The {@link AddPoolsConfiguration} class registers {@link org.springframework.data.gemfire.client.PoolFactoryBean} + * bean definitions for all {@link EnablePool} annotation configuration meta-data defined in + * the {@link EnablePools} annotation on a GemFire client cache application class. + + * @author John Blum + * @see org.springframework.data.gemfire.config.annotation.AddPoolConfiguration + * @see org.springframework.data.gemfire.config.annotation.EnablePool + * @see org.springframework.data.gemfire.config.annotation.EnablePools + * @since 1.9.0 + */ +public class AddPoolsConfiguration extends AddPoolConfiguration { + + /** + * {@inheritDoc} + */ + @Override + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { + if (importingClassMetadata.hasAnnotation(EnablePools.class.getName())) { + Map enablePoolsAttributes = importingClassMetadata.getAnnotationAttributes( + EnablePools.class.getName()); + + AnnotationAttributes[] serversAttributes = (AnnotationAttributes[]) enablePoolsAttributes.get("pools"); + + for (AnnotationAttributes enablePoolAttributes : serversAttributes) { + registerPoolFactoryBeanDefinition(enablePoolAttributes, registry); + } + } + } +} diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/CacheServerConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/CacheServerConfiguration.java index cbefe88b..d0177b03 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/CacheServerConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/CacheServerConfiguration.java @@ -31,6 +31,8 @@ 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; +import org.springframework.data.gemfire.util.CollectionUtils; +import org.springframework.data.gemfire.util.SpringUtils; /** * Spring {@link Configuration} class used to configure, construct and initialize and GemFire {@link CacheServer} @@ -153,7 +155,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected String bindAddress() { - return nullSafeValue(this.bindAddress, CacheServer.DEFAULT_BIND_ADDRESS); + return SpringUtils.defaultIfNull(this.bindAddress, CacheServer.DEFAULT_BIND_ADDRESS); } /* (non-Javadoc) */ @@ -162,7 +164,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected String hostnameForClients() { - return nullSafeValue(this.hostnameForClients, CacheServer.DEFAULT_HOSTNAME_FOR_CLIENTS); + return SpringUtils.defaultIfNull(this.hostnameForClients, CacheServer.DEFAULT_HOSTNAME_FOR_CLIENTS); } /* (non-Javadoc) */ @@ -171,7 +173,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected Set interestRegistrationListeners() { - return nullSafeSet(this.interestRegistrationListeners); + return CollectionUtils.nullSafeSet(this.interestRegistrationListeners); } /* (non-Javadoc) */ @@ -180,7 +182,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected Long loadPollInterval() { - return nullSafeValue(this.loadPollInterval, CacheServer.DEFAULT_LOAD_POLL_INTERVAL); + return SpringUtils.defaultIfNull(this.loadPollInterval, CacheServer.DEFAULT_LOAD_POLL_INTERVAL); } /* (non-Javadoc) */ @@ -189,7 +191,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected Integer maxConnections() { - return nullSafeValue(this.maxConnections, CacheServer.DEFAULT_MAX_CONNECTIONS); + return SpringUtils.defaultIfNull(this.maxConnections, CacheServer.DEFAULT_MAX_CONNECTIONS); } /* (non-Javadoc) */ @@ -198,7 +200,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected Integer maxMessageCount() { - return nullSafeValue(this.maxMessageCount, CacheServer.DEFAULT_MAXIMUM_MESSAGE_COUNT); + return SpringUtils.defaultIfNull(this.maxMessageCount, CacheServer.DEFAULT_MAXIMUM_MESSAGE_COUNT); } /* (non-Javadoc) */ @@ -207,7 +209,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected Integer maxThreads() { - return nullSafeValue(this.maxThreads, CacheServer.DEFAULT_MAX_THREADS); + return SpringUtils.defaultIfNull(this.maxThreads, CacheServer.DEFAULT_MAX_THREADS); } /* (non-Javadoc) */ @@ -216,7 +218,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected Integer maxTimeBetweenPings() { - return nullSafeValue(this.maxTimeBetweenPings, CacheServer.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS); + return SpringUtils.defaultIfNull(this.maxTimeBetweenPings, CacheServer.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS); } /* (non-Javadoc) */ @@ -225,7 +227,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected Integer messageTimeToLive() { - return nullSafeValue(this.messageTimeToLive, CacheServer.DEFAULT_MESSAGE_TIME_TO_LIVE); + return SpringUtils.defaultIfNull(this.messageTimeToLive, CacheServer.DEFAULT_MESSAGE_TIME_TO_LIVE); } /* (non-Javadoc) */ @@ -234,7 +236,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected Integer port() { - return nullSafeValue(this.port, CacheServer.DEFAULT_PORT); + return SpringUtils.defaultIfNull(this.port, CacheServer.DEFAULT_PORT); } /* (non-Javadoc) */ @@ -243,7 +245,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected ServerLoadProbe serverLoadProbe() { - return nullSafeValue(this.serverLoadProbe, CacheServer.DEFAULT_LOAD_PROBE); + return SpringUtils.defaultIfNull(this.serverLoadProbe, CacheServer.DEFAULT_LOAD_PROBE); } /* (non-Javadoc) */ @@ -252,7 +254,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected Integer socketBufferSize() { - return nullSafeValue(this.socketBufferSize, CacheServer.DEFAULT_SOCKET_BUFFER_SIZE); + return SpringUtils.defaultIfNull(this.socketBufferSize, CacheServer.DEFAULT_SOCKET_BUFFER_SIZE); } /* (non-Javadoc) */ @@ -261,7 +263,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected Integer subscriptionCapacity() { - return nullSafeValue(this.subscriptionCapacity, ClientSubscriptionConfig.DEFAULT_CAPACITY); + return SpringUtils.defaultIfNull(this.subscriptionCapacity, ClientSubscriptionConfig.DEFAULT_CAPACITY); } /* (non-Javadoc) */ @@ -279,7 +281,7 @@ public class CacheServerConfiguration extends PeerCacheConfiguration { } protected SubscriptionEvictionPolicy subscriptionEvictionPolicy() { - return nullSafeValue(this.subscriptionEvictionPolicy, SubscriptionEvictionPolicy.DEFAULT); + return SpringUtils.defaultIfNull(this.subscriptionEvictionPolicy, SubscriptionEvictionPolicy.DEFAULT); } @Override diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.java b/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.java index 9ee49cd5..06fcccda 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.java @@ -32,13 +32,13 @@ import org.springframework.context.annotation.Import; import org.springframework.data.gemfire.GemfireUtils; /** - * The ClientCacheApplication annotation enables a Spring Data GemFire based application to become + * The {@link 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 org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration * @see com.gemstone.gemfire.cache.client.PoolFactory * @see com.gemstone.gemfire.cache.control.ResourceManager * @since 1.9.0 @@ -95,7 +95,7 @@ public @interface ClientCacheApplication { int freeConnectionTimeout() default PoolFactory.DEFAULT_FREE_CONNECTION_TIMEOUT; /** - * Conifgures the amount of time a connection can be idle before expiring the connection. + * Configures the amount of time a connection can be idle before expiring the connection. * * @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_IDLE_TIMEOUT */ @@ -113,7 +113,7 @@ public @interface ClientCacheApplication { * * @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_LOAD_CONDITIONING_INTERVAL */ - int loadConditionInterval() default PoolFactory.DEFAULT_LOAD_CONDITIONING_INTERVAL; + int loadConditioningInterval() default PoolFactory.DEFAULT_LOAD_CONDITIONING_INTERVAL; /** * Configures the GemFire {@link com.gemstone.gemfire.distributed.Locator}s to which diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheConfiguration.java index 9b50cdd1..305bdead 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/ClientCacheConfiguration.java @@ -17,8 +17,6 @@ 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; @@ -28,6 +26,7 @@ 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; +import org.springframework.data.gemfire.support.ConnectionEndpointList; /** * Spring {@link Configuration} class used to configure, construct and initialize @@ -110,6 +109,9 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration { return gemfireCache; } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") protected T newCacheFactoryBean() { @@ -136,7 +138,7 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration { setFreeConnectionTimeout((Integer) clientCacheApplicationAttributes.get("freeConnectionTimeout")); setIdleTimeout((Long) clientCacheApplicationAttributes.get("idleTimeout")); setKeepAlive(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("keepAlive"))); - setLoadConditioningInterval((Integer) clientCacheApplicationAttributes.get("loadConditionInterval")); + setLoadConditioningInterval((Integer) clientCacheApplicationAttributes.get("loadConditioningInterval")); setMaxConnections((Integer) clientCacheApplicationAttributes.get("maxConnections")); setMinConnections((Integer) clientCacheApplicationAttributes.get("minConnections")); setMultiUserAuthentication(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("multiUserAuthentication"))); @@ -154,35 +156,50 @@ public class ClientCacheConfiguration extends AbstractCacheConfiguration { setSubscriptionRedundancy((Integer) clientCacheApplicationAttributes.get("subscriptionRedundancy")); setThreadLocalConnections(Boolean.TRUE.equals(clientCacheApplicationAttributes.get("threadLocalConnections"))); - configureLocatorOrServer(clientCacheApplicationAttributes); + configureLocatorsAndServers(clientCacheApplicationAttributes); } } - /* (non-Javadoc) */ - void configureLocatorOrServer(Map clientCacheApplicationAttributes) { - AnnotationAttributes[] locators = - (AnnotationAttributes[]) clientCacheApplicationAttributes.get("locators"); + /** + * Uses the list of GemFire Locator and Server connection endpoint definitions and meta-data to configure + * the GemFire client {@link com.gemstone.gemfire.cache.client.Pool} used to communicate with the servers + * in the GemFire cluster. + * + * @param clientCacheApplicationAttributes {@link ClientCacheApplication} annotation containing + * {@link com.gemstone.gemfire.cache.client.Pool} Locator/Server connection endpoint meta-data. + * @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication + * @see java.util.Map + */ + protected void configureLocatorsAndServers(Map clientCacheApplicationAttributes) { + ConnectionEndpointList poolLocators = new ConnectionEndpointList(); - List poolLocators = new ArrayList(locators.length); + AnnotationAttributes[] locators = (AnnotationAttributes[]) clientCacheApplicationAttributes.get("locators"); for (AnnotationAttributes locator : locators) { - poolLocators.add(new ConnectionEndpoint((String) locator.get("host"), (Integer) locator.get("port"))); + poolLocators.add(newConnectionEndpoint((String) locator.get("host"), (Integer) locator.get("port"))); } setPoolLocators(poolLocators); - AnnotationAttributes[] servers = - (AnnotationAttributes[]) clientCacheApplicationAttributes.get("servers"); + ConnectionEndpointList poolServers = new ConnectionEndpointList(); - List poolServers = new ArrayList(servers.length); + AnnotationAttributes[] servers = (AnnotationAttributes[]) clientCacheApplicationAttributes.get("servers"); for (AnnotationAttributes server : servers) { - poolServers.add(new ConnectionEndpoint((String) server.get("host"), (Integer) server.get("port"))); + poolServers.add(newConnectionEndpoint((String) server.get("host"), (Integer) server.get("port"))); } setPoolServers(poolServers); } + /* (non-Javadoc) */ + protected ConnectionEndpoint newConnectionEndpoint(String host, Integer port) { + return new ConnectionEndpoint(host, port); + } + + /** + * {@inheritDoc} + */ @Override protected Class getAnnotationType() { return ClientCacheApplication.class; diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableCacheServer.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableCacheServer.java index c8d46d7f..c7dc909a 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableCacheServer.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableCacheServer.java @@ -27,21 +27,29 @@ import java.lang.annotation.Target; 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 EnableCacheServer class... + * The {@link EnableCacheServer} annotation configures a Spring {@link org.springframework.context.annotation.Configuration} + * annotated class with a GemFire {@link CacheServer} bean in the Spring application context. * + * This annotation is used in conjunction with the {@link CacheServerApplication}, or {@link PeerCacheApplication} + * annotations to add an additional {@link CacheServer CacheServers} to a GemFire peer cache application + * configured with Spring (Data GemFire). + * + * To add more than 1 {@link CacheServer} to your application, this annotation can be nested in + * the {@link EnableCacheServers} annotation. + * @author John Blum - * @since 1.0.0 + * @see org.springframework.data.gemfire.config.annotation.AddCacheServerConfiguration + * @see com.gemstone.gemfire.cache.server.CacheServer + * @since 1.9.0 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented -@Configuration @Import(AddCacheServerConfiguration.class) @SuppressWarnings("unused") public @interface EnableCacheServer { diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableCacheServers.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableCacheServers.java index cf123031..0db7d480 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableCacheServers.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableCacheServers.java @@ -24,24 +24,28 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; /** - * The EnableCacheServers class... + * The {@link EnableCacheServers} annotation enables 1 or more GemFire {@link com.gemstone.gemfire.cache.server.CacheServer CacheServers} + * to be defined and used in a GemFire peer cache application configured with Spring (Data GemFire). * * @author John Blum - * @since 1.0.0 + * @see org.springframework.data.gemfire.config.annotation.AddCacheServersConfiguration + * @see org.springframework.data.gemfire.config.annotation.EnableCacheServer + * @since 1.9.0 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented -@Configuration @Import(AddCacheServersConfiguration.class) @SuppressWarnings("unused") public @interface EnableCacheServers { + /** + * Enables the definition of multiple GemFire {@link com.gemstone.gemfire.cache.server.CacheServer CacheServers}. + */ EnableCacheServer[] servers() default {}; } diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/WithGemFireProperties.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableGemFireProperties.java similarity index 99% rename from src/main/java/org/springframework/data/gemfire/config/annotation/WithGemFireProperties.java rename to src/main/java/org/springframework/data/gemfire/config/annotation/EnableGemFireProperties.java index 0e8607bf..0a273212 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/WithGemFireProperties.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableGemFireProperties.java @@ -27,7 +27,7 @@ import java.lang.annotation.Target; import org.springframework.context.annotation.Import; /** - * The WithGemFireProperties annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration} + * The {@link EnableGemFireProperties} annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration} * annotated class to configure GemFire/Geode System properties at runtime during [Spring Boot] application startup. * * @author John Blum @@ -42,7 +42,7 @@ import org.springframework.context.annotation.Import; @Documented @Import(GemFirePropertiesConfiguration.class) @SuppressWarnings("unused") -public @interface WithGemFireProperties { +public @interface EnableGemFireProperties { /** * Number of seconds the distributed system will wait after the {@literal ack-wait-threshold} for a message diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnablePool.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnablePool.java new file mode 100644 index 00000000..c5ea6eb8 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnablePool.java @@ -0,0 +1,235 @@ +/* + * 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.Pool; +import com.gemstone.gemfire.cache.client.PoolFactory; + +import org.springframework.context.annotation.Import; +import org.springframework.data.gemfire.GemfireUtils; + +/** + * The {@link EnablePool} annotation configures a Spring {@link org.springframework.context.annotation.Configuration} + * annotated class with a "named" GemFire client {@link Pool} bean in the application context. + * + * This annotation is used in conjunction with the {@link ClientCacheApplication} annotation to add an additional + * {@link Pool} to a GemFire cache client application configured with Spring (Data GemFire). + * + * To add more than 1 {@link Pool} to your application, this annotation can be nested in the {@link EnablePools} + * annotation. + * + * @author John Blum + * @see org.springframework.data.gemfire.config.annotation.AddPoolConfiguration + * @see com.gemstone.gemfire.cache.client.Pool + * @see com.gemstone.gemfire.cache.client.PoolFactory + * @since 1.9.0 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Documented +@Import(AddPoolConfiguration.class) +@SuppressWarnings("unused") +public @interface EnablePool { + + /** + * 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; + + /** + * Configures 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 the load conditioning interval for this pool. + * + * @see com.gemstone.gemfire.cache.client.PoolFactory#DEFAULT_LOAD_CONDITIONING_INTERVAL + */ + int loadConditioningInterval() default PoolFactory.DEFAULT_LOAD_CONDITIONING_INTERVAL; + + /** + * Configures the GemFire {@link com.gemstone.gemfire.distributed.Locator Locators} to which + * this cache client will connect. + */ + Locator[] locators() default {}; + + /** + * A {@link String} containing a comma-delimited list of hosts and ports defining the connection endpoints + * of GemFire Locators in the cluster. + * + * The {@link String} must be formatted as: 'host1[port], host2[port], ..., hostN[port]'. + */ + String locatorsString() default ""; + + /** + * 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; + + /** + * Specifies the name of the GemFire client {@link Pool}. + */ + String 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 {@literal 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; + + /** + * 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 CacheServers} to which + * this cache client will connect. + */ + Server[] servers() default {}; + + /** + * A {@link String} containing a comma-delimited list of hosts and ports defining the connection endpoints + * of GemFire Servers in the cluster. + * + * The {@link String} must be formatted as: 'host1[port], host2[port], ..., hostN[port]'. + */ + String serversString() 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; + + } +} diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnablePools.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnablePools.java new file mode 100644 index 00000000..04821fa8 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnablePools.java @@ -0,0 +1,51 @@ +/* + * 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 {@link EnablePools} annotation enables 1 or more GemFire {@link com.gemstone.gemfire.cache.client.Pool Pools} + * to be defined and used in a GemFire client cache application configured with Spring (Data GemFire). + * + * @author John Blum + * @see org.springframework.data.gemfire.config.annotation.AddPoolsConfiguration + * @see org.springframework.data.gemfire.config.annotation.EnablePool + * @since 1.9.0 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Documented +@Import(AddPoolsConfiguration.class) +@SuppressWarnings("unused") +public @interface EnablePools { + + /** + * Enables the definition of multiple GemFire {@link com.gemstone.gemfire.cache.client.Pool Pools}. + */ + EnablePool[] pools() default {}; + +} diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/GemFirePropertiesConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/GemFirePropertiesConfiguration.java index 3a3973ca..e333bd42 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/GemFirePropertiesConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/GemFirePropertiesConfiguration.java @@ -24,12 +24,12 @@ import org.springframework.data.gemfire.config.annotation.support.EmbeddedServic import org.springframework.data.gemfire.util.PropertiesBuilder; /** - * The GemFirePropertiesConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar} - * capable of configuring additional GemFire Properties on the (Spring Boot) application class at runtime + * The {@link GemFirePropertiesConfiguration} class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar} + * capable of configuring additional GemFire Properties on a (Spring Boot) application class at runtime * during startup. * * @author John Blum - * @see org.springframework.data.gemfire.config.annotation.WithGemFireProperties + * @see org.springframework.data.gemfire.config.annotation.EnableGemFireProperties * @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport * @since 1.9.0 */ @@ -69,7 +69,7 @@ public class GemFirePropertiesConfiguration extends EmbeddedServiceConfiguration /* (non-Javadoc) */ @Override protected Class getAnnotationType() { - return WithGemFireProperties.class; + return EnableGemFireProperties.class; } /* (non-Javadoc) */ diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.java b/src/main/java/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.java index b1e67445..87e8830c 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.java @@ -30,7 +30,7 @@ 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} + * The {@link PeerCacheApplication} annotation enables an embedded GemFire peer {@link com.gemstone.gemfire.cache.Cache} * instance in a Spring Data GemFire based application. * * @author John Blum diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/PeerCacheConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/PeerCacheConfiguration.java index f6ff58ee..202da39d 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/PeerCacheConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/PeerCacheConfiguration.java @@ -26,7 +26,7 @@ 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. + * a GemFire peer {@link com.gemstone.gemfire.cache.Cache} instance in a Spring application context. * * @author John Blum * @see org.springframework.context.annotation.Bean @@ -67,6 +67,9 @@ public class PeerCacheConfiguration extends AbstractCacheConfiguration { return gemfireCache; } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") protected T newCacheFactoryBean() { @@ -103,6 +106,9 @@ public class PeerCacheConfiguration extends AbstractCacheConfiguration { } } + /** + * {@inheritDoc} + */ @Override protected Class getAnnotationType() { return PeerCacheApplication.class; diff --git a/src/main/java/org/springframework/data/gemfire/server/CacheServerFactoryBean.java b/src/main/java/org/springframework/data/gemfire/server/CacheServerFactoryBean.java index 2bda2f26..261ccbf8 100644 --- a/src/main/java/org/springframework/data/gemfire/server/CacheServerFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/server/CacheServerFactoryBean.java @@ -40,8 +40,8 @@ import org.springframework.util.StringUtils; * @author John Blum */ @SuppressWarnings("unused") -public class CacheServerFactoryBean implements FactoryBean, InitializingBean, DisposableBean, - SmartLifecycle { +public class CacheServerFactoryBean implements FactoryBean, + InitializingBean, DisposableBean, SmartLifecycle { private boolean autoStartup = true; private boolean notifyBySubscription = CacheServer.DEFAULT_NOTIFY_BY_SUBSCRIPTION; @@ -73,18 +73,9 @@ public class CacheServerFactoryBean implements FactoryBean, Initial private SubscriptionEvictionPolicy subscriptionEvictionPolicy = SubscriptionEvictionPolicy.DEFAULT; - public CacheServer getObject() { - return cacheServer; - } - - public Class getObjectType() { - return (this.cacheServer != null ? cacheServer.getClass() : CacheServer.class); - } - - public boolean isSingleton() { - return true; - } - + /** + * {@inheritDoc} + */ @SuppressWarnings("deprecation") public void afterPropertiesSet() throws IOException { Assert.notNull(cache, "A GemFire Cache is required."); @@ -118,24 +109,51 @@ public class CacheServerFactoryBean implements FactoryBean, Initial } } - public boolean isAutoStartup() { - return autoStartup; + /** + * {@inheritDoc} + */ + public CacheServer getObject() { + return cacheServer; } + /** + * {@inheritDoc} + */ + public Class getObjectType() { + return (this.cacheServer != null ? cacheServer.getClass() : CacheServer.class); + } + + /** + * {@inheritDoc} + */ + public boolean isSingleton() { + return true; + } + + /* (non-Javadoc) */ public boolean isRunning() { return (cacheServer != null && cacheServer.isRunning()); } + /* (non-Javadoc) */ + public boolean isAutoStartup() { + return autoStartup; + } + + /** + * Start at the latest possible moment. + */ public int getPhase() { - // start at the latest possible moment return Integer.MAX_VALUE; } + /* (non-Javadoc) */ public void destroy() { stop(); cacheServer = null; } + /* (non-Javadoc) */ public void start() { try { cacheServer.start(); @@ -145,26 +163,31 @@ public class CacheServerFactoryBean implements FactoryBean, Initial } } + /* (non-Javadoc) */ public void stop(final Runnable callback) { stop(); callback.run(); } + /* (non-Javadoc) */ public void stop() { if (cacheServer != null) { cacheServer.stop(); } } + /* (non-Javadoc) */ public void setAutoStartup(boolean autoStartup) { this.autoStartup = autoStartup; } + /* (non-Javadoc) */ public void setBindAddress(String bindAddress) { this.bindAddress = bindAddress; } - public void setCache(final Cache cache) { + /* (non-Javadoc) */ + public void setCache(Cache cache) { this.cache = cache; } @@ -172,76 +195,92 @@ public class CacheServerFactoryBean implements FactoryBean, Initial * (non-Javadoc) * For testing purposes only! */ - void setCacheServer(final CacheServer cacheServer) { + void setCacheServer(CacheServer cacheServer) { this.cacheServer = cacheServer; } + /* (non-Javadoc) */ public void setHostNameForClients(String hostNameForClients) { this.hostNameForClients = hostNameForClients; } + /* (non-Javadoc) */ public void setListeners(Set listeners) { this.listeners = listeners; } + /* (non-Javadoc) */ public void setLoadPollInterval(long loadPollInterval) { this.loadPollInterval = loadPollInterval; } + /* (non-Javadoc) */ public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; } + /* (non-Javadoc) */ public void setMaxMessageCount(int maxMessageCount) { this.maxMessageCount = maxMessageCount; } + /* (non-Javadoc) */ public void setMaxThreads(int maxThreads) { this.maxThreads = maxThreads; } + /* (non-Javadoc) */ public void setMaxTimeBetweenPings(int maxTimeBetweenPings) { this.maxTimeBetweenPings = maxTimeBetweenPings; } + /* (non-Javadoc) */ public void setMessageTimeToLive(int messageTimeToLive) { this.messageTimeToLive = messageTimeToLive; } + /* (non-Javadoc) */ public void setNotifyBySubscription(boolean notifyBySubscription) { this.notifyBySubscription = notifyBySubscription; } + /* (non-Javadoc) */ public void setPort(int port) { this.port = port; } + /* (non-Javadoc) */ public void setServerGroups(String[] serverGroups) { this.serverGroups = serverGroups; } + /* (non-Javadoc) */ public void setServerLoadProbe(ServerLoadProbe serverLoadProbe) { this.serverLoadProbe = serverLoadProbe; } + /* (non-Javadoc) */ public void setSocketBufferSize(int socketBufferSize) { this.socketBufferSize = socketBufferSize; } + /* (non-Javadoc) */ public void setSubscriptionCapacity(int subscriptionCapacity) { this.subscriptionCapacity = subscriptionCapacity; } + /* (non-Javadoc) */ public void setSubscriptionDiskStore(String diskStoreName) { this.subscriptionDiskStore = diskStoreName; } + /* (non-Javadoc) */ SubscriptionEvictionPolicy getSubscriptionEvictionPolicy() { return (subscriptionEvictionPolicy != null ? subscriptionEvictionPolicy : SubscriptionEvictionPolicy.DEFAULT); } + /* (non-Javadoc) */ public void setSubscriptionEvictionPolicy(SubscriptionEvictionPolicy evictionPolicy) { this.subscriptionEvictionPolicy = evictionPolicy; } - }