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 75ef85ea..ddfcda84 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
@@ -20,6 +20,7 @@ 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.lang.annotation.Annotation;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -40,6 +41,7 @@ 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.data.gemfire.util.PropertiesBuilder;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -57,6 +59,7 @@ 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.type.AnnotationMetadata
* @since 1.9.0
*/
@SuppressWarnings("unused")
@@ -66,6 +69,8 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
protected static final boolean DEFAULT_COPY_ON_READ = false;
protected static final boolean DEFAULT_USE_BEAN_FACTORY_LOCATOR = false;
+ protected static final int DEFAULT_MCAST_PORT = 0;
+
protected static final String DEFAULT_LOG_LEVEL = "config";
protected static final String DEFAULT_NAME = "SpringDataGemFireApplication";
@@ -83,6 +88,8 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
private DynamicRegionSupport dynamicRegionSupport;
+ private Integer mcastPort = 0;
+
private Float criticalHeapPercentage;
private Float evictionHeapPercentage;
@@ -93,12 +100,15 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
private PdxSerializer pdxSerializer;
+ private PropertiesBuilder customGemFireProperties = new PropertiesBuilder();
+
private Resource cacheXml;
private String locators = "";
private String logLevel = DEFAULT_LOG_LEVEL;
private String name;
private String pdxDiskStoreName;
+ private String startLocator;
private TransactionWriter transactionWriter;
@@ -174,19 +184,18 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
}
/**
- * Returns a {@link Properties} object containing GemFire System properties used to configure
- * the GemFire cache.
+ * 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.
+ * The name of the GemFire member/node in the cluster is set to a default, pre-defined, descriptive value
+ * depending on the type of configuration meta-data 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.
+ * for {@link com.gemstone.gemfire.cache.client.ClientCache cache client}-based applications. These values
+ * can be changed for peer cache and cache server applications.
*
- * Finally GemFire's "log-level" System property defaults to "config".
+ * Finally, GemFire's {@literal log-level} System property defaults to {@literal config}.
*
- * @return a {@link Properties} object containing GemFire System properties used to configure
- * the GemFire cache.
+ * @return a {@link Properties} object containing GemFire System properties used to configure the GemFire cache.
* @see GemFire Properties
* @see java.util.Properties
* @see #name()
@@ -195,12 +204,16 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
*/
@Bean
protected Properties gemfireProperties() {
- Properties gemfireProperties = new Properties();
+ PropertiesBuilder gemfireProperties = new PropertiesBuilder();
+
gemfireProperties.setProperty("name", name());
- gemfireProperties.setProperty("mcast-port", "0");
+ gemfireProperties.setProperty("mcast-port", mcastPort());
gemfireProperties.setProperty("log-level", logLevel());
gemfireProperties.setProperty("locators", locators());
- return gemfireProperties;
+ gemfireProperties.setProperty("start-locator", startLocator());
+ gemfireProperties.add(customGemFireProperties);
+
+ return gemfireProperties.build();
}
/*
@@ -213,7 +226,7 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
}
/**
- * Gets a reference to the {@link ClassLoader} use by the Spring {@link BeanFactory} to load classes
+ * Returns 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.
@@ -233,7 +246,7 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
}
/**
- * Gets a reference to the Spring {@link BeanFactory} in the current application context.
+ * Returns 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.
@@ -252,6 +265,7 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
configureCache(importMetadata);
+ configureMemcachedServer(importMetadata);
configurePdx(importMetadata);
configureOther(importMetadata);
}
@@ -287,6 +301,32 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
}
}
+ /**
+ * Configures the embedded GemFire Memcached Server (Gemcached) service in a GemFire server/data node.
+ *
+ * @param importMetadata {@link AnnotationMetadata} containing the Gemcached meta-data used to configure
+ * the embedded GemFire Memcached Server (Gemcached) service.
+ * @see org.springframework.core.type.AnnotationMetadata
+ */
+ protected void configureMemcachedServer(AnnotationMetadata importMetadata) {
+ if (isCacheServerApplication(importMetadata) || isPeerCacheApplication(importMetadata)) {
+ if (importMetadata.hasAnnotation(EnableMemcachedServer.class.getName())) {
+ Map enableMemcachedServerAttributes =
+ importMetadata.getAnnotationAttributes(EnableMemcachedServer.class.getName());
+
+ Properties gemfireMemcachedProperties = new Properties();
+
+ gemfireMemcachedProperties.setProperty("memcached-port",
+ String.valueOf(enableMemcachedServerAttributes.get("port")));
+
+ gemfireMemcachedProperties.setProperty("memcached-protocol",
+ String.valueOf(enableMemcachedServerAttributes.get("protocol")));
+
+ add(gemfireMemcachedProperties);
+ }
+ }
+ }
+
/**
* Configures GemFire's PDX Serialization feature.
*
@@ -367,12 +407,10 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
* 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()
+ * @see #isTypedCacheApplication(Class, AnnotationMetadata)
*/
protected boolean isCacheServerApplication(AnnotationMetadata importMetadata) {
- return (CacheServerApplication.class.equals(getAnnotationType())
- && importMetadata.hasAnnotation(getAnnotationTypeName()));
+ return isTypedCacheApplication(CacheServerApplication.class, importMetadata);
}
/**
@@ -384,12 +422,10 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
* 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()
+ * @see #isTypedCacheApplication(Class, AnnotationMetadata)
*/
protected boolean isClientCacheApplication(AnnotationMetadata importMetadata) {
- return (ClientCacheApplication.class.equals(getAnnotationType())
- && importMetadata.hasAnnotation(getAnnotationTypeName()));
+ return isTypedCacheApplication(ClientCacheApplication.class, importMetadata);
}
/**
@@ -401,21 +437,38 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
* 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 #isTypedCacheApplication(Class, AnnotationMetadata)
+ */
+ protected boolean isPeerCacheApplication(AnnotationMetadata importMetadata) {
+ return isTypedCacheApplication(PeerCacheApplication.class, importMetadata);
+ }
+
+ /**
+ * Determines whether this Spring application is annotated with the given GemFire cache type annotation.
+ *
+ * @param annotationType {@link Annotation} cache type.
+ * @param importMetadata {@link AnnotationMetadata} containing application configuration meta-data
+ * from the annotations used to configure the Spring application.
+ * @return a boolean value indicating if this Spring application is annotated with the given GemFire
+ * cache type annotation.
+ * @see org.springframework.core.type.AnnotationMetadata
+ * @see java.lang.annotation.Annotation
* @see #getAnnotationTypeName()
* @see #getAnnotationType()
*/
- protected boolean isPeerCacheApplication(AnnotationMetadata importMetadata) {
- return (PeerCacheApplication.class.equals(getAnnotationType())
- && importMetadata.hasAnnotation(getAnnotationTypeName()));
+ protected boolean isTypedCacheApplication(Class extends Annotation> annotationType,
+ AnnotationMetadata importMetadata) {
+
+ return (annotationType.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
+ * {@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,
+ * from the class type-level 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)
@@ -427,12 +480,13 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
}
/**
- * Constructs a new, initialized instance of the {@link CacheFactoryBean} based on the application
- * GemFire cache type (i.e. client or peer).
+ * Constructs a new, initialized instance of the {@link CacheFactoryBean} based on the Spring application's
+ * GemFire cache type (i.e. client or peer) preference specified via annotation.
*
* @param 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).
+ * @return a new instance of an appropriate {@link CacheFactoryBean} given the Spring application's
+ * GemFire cache type preference (i.e client or peer) specified with the corresponding annotation
+ * (e.g. {@link ClientCacheApplication} or {@link PeerCacheApplication});
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
* @see org.springframework.data.gemfire.CacheFactoryBean
* @see #setCommonCacheConfiguration(CacheFactoryBean)
@@ -443,12 +497,13 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
}
/**
- * Constructs a new, uninitialized instance of the {@link CacheFactoryBean} based on the application
- * GemFire cache type (i.e. client or peer).
+ * Constructs a new, uninitialized instance of the {@link CacheFactoryBean} based on the Spring application's
+ * GemFire cache type (i.e. client or peer) preference specified via annotation.
*
* @param 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).
+ * @return a new instance of an appropriate {@link CacheFactoryBean} given the Spring application's
+ * GemFire cache type preference (i.e client or peer) specified with the corresponding annotation
+ * (e.g. {@link ClientCacheApplication} or {@link PeerCacheApplication}).
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
* @see org.springframework.data.gemfire.CacheFactoryBean
*/
@@ -458,7 +513,7 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
* Configures common GemFire cache configuration settings.
*
* @param Class type of the {@link CacheFactoryBean}.
- * @param gemfireCache specific {@link CacheFactoryBean} instance to configure.
+ * @param gemfireCache {@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
@@ -558,6 +613,7 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
return nullSafeList(this.jndiDataSources);
}
+ /* (non-Javadoc) */
void setLocators(String locators) {
this.locators = locators;
}
@@ -575,6 +631,15 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
return nullSafeValue(this.logLevel, DEFAULT_LOG_LEVEL);
}
+ void setMcastPort(Integer mcastPort) {
+ this.mcastPort = mcastPort;
+ }
+
+ protected Integer mcastPort() {
+ return (mcastPort != null ? mcastPort : DEFAULT_MCAST_PORT);
+ }
+
+ /* (non-Javadoc) */
void setName(String name) {
this.name = name;
}
@@ -628,6 +693,15 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
return this.pdxSerializer;
}
+ /* (non-Javadoc) */
+ void setStartLocator(String startLocator) {
+ this.startLocator = startLocator;
+ }
+
+ protected String startLocator() {
+ return this.startLocator;
+ }
+
/* (non-Javadoc) */
void setTransactionListeners(List transactionListeners) {
this.transactionListeners = transactionListeners;
@@ -655,6 +729,10 @@ public abstract class AbstractCacheConfiguration implements BeanFactoryAware, Be
return this.useBeanFactoryLocator;
}
+ public void add(Properties gemfireProperties) {
+ customGemFireProperties.add(gemfireProperties);
+ }
+
@Override
public String toString() {
return DEFAULT_NAME;
diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/CacheServerApplication.java b/src/main/java/org/springframework/data/gemfire/config/annotation/CacheServerApplication.java
index f4782fb3..e07087b8 100644
--- a/src/main/java/org/springframework/data/gemfire/config/annotation/CacheServerApplication.java
+++ b/src/main/java/org/springframework/data/gemfire/config/annotation/CacheServerApplication.java
@@ -60,7 +60,7 @@ public @interface CacheServerApplication {
/**
* Configures whether the {@link CacheServer} should start automatically at runtime.
*
- * Default is {@code true).
+ * Default is {@literal true).
*/
boolean autoStartup() default true;
@@ -74,7 +74,7 @@ public @interface CacheServerApplication {
/**
* Indicates whether the "copy on read" is enabled for this cache.
*
- * Default is {@code false}.
+ * Default is {@literal false}.
*/
boolean copyOnRead() default false;
@@ -90,7 +90,7 @@ public @interface CacheServerApplication {
* after it has been forced out of the distributed system by a network partition event or has otherwise been
* shunned by other members. Use this property to enable the auto-reconnect behavior.
*
- * Default is {@code false}.
+ * Default is {@literal false}.
*/
boolean enableAutoReconnect() default false;
@@ -238,7 +238,7 @@ public @interface CacheServerApplication {
* Configures whether this GemFire cache member node would pull it's configuration meta-data
* from the cluster-based Cluster Configuration service.
*
- * Default is {@code false}.
+ * Default is {@literal false}.
*/
boolean useClusterConfiguration() default false;
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 d5e28b6b..d97b1b6b 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
@@ -55,7 +55,7 @@ public @interface ClientCacheApplication {
/**
* Indicates whether the "copy on read" is enabled for this cache.
*
- * Default is {@code false}.
+ * Default is {@literal false}.
*/
boolean copyOnRead() default false;
@@ -104,7 +104,7 @@ public @interface ClientCacheApplication {
/**
* Configures whether to keep the client queues alive on the server when the client is disconnected
*
- * Default is {@code false}.
+ * Default is {@literal false}.
*/
boolean keepAlive() default false;
@@ -164,7 +164,7 @@ public @interface ClientCacheApplication {
long pingInterval() default PoolFactory.DEFAULT_PING_INTERVAL;
/**
- * By default {@code prSingleHopEnabled} is {@code true} in which case the client is aware of the location
+ * 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
@@ -182,7 +182,7 @@ public @interface ClientCacheApplication {
/**
* Notifies the server that this durable client is ready to receive updates.
*
- * Default is {@code false}.
+ * Default is {@literal false}.
*/
boolean readyForEvents() default false;
diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EmbeddedLocatorConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EmbeddedLocatorConfiguration.java
index eae66619..36576bdb 100644
--- a/src/main/java/org/springframework/data/gemfire/config/annotation/EmbeddedLocatorConfiguration.java
+++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EmbeddedLocatorConfiguration.java
@@ -20,19 +20,26 @@ package org.springframework.data.gemfire.config.annotation;
import java.util.Map;
import java.util.Properties;
+import org.springframework.data.gemfire.GemfireUtils;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
+import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
- * The EmbeddedManagerConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
+ * The EmbeddedLocatorConfiguration 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
+ * @see org.springframework.data.gemfire.config.annotation.EnableEmbeddedLocator
+ * @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
*/
public class EmbeddedLocatorConfiguration extends EmbeddedServiceConfigurationSupport {
+ protected static final int DEFAULT_LOCATOR_PORT = GemfireUtils.DEFAULT_LOCATOR_PORT;
+
+ protected static final String START_LOCATOR_GEMFIRE_SYSTEM_PROPERTY_NAME = "start-locator";
+
@Override
protected Class getAnnotationType() {
return EnableEmbeddedLocator.class;
@@ -40,10 +47,11 @@ public class EmbeddedLocatorConfiguration extends EmbeddedServiceConfigurationSu
@Override
protected Properties toGemFireProperties(Map annotationAttributes) {
- Properties gemfireProperties = new Properties();
+ String host = resolveHost((String) annotationAttributes.get("host"));
+ int port = resolvePort((Integer) annotationAttributes.get("port"), DEFAULT_LOCATOR_PORT);
- setProperty(gemfireProperties, "start-locator", annotationAttributes.get("startLocator"));
-
- return gemfireProperties;
+ return new PropertiesBuilder()
+ .setProperty(START_LOCATOR_GEMFIRE_SYSTEM_PROPERTY_NAME, String.format("%s[%d]", host, port))
+ .build();
}
}
diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EmbeddedManagerConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EmbeddedManagerConfiguration.java
index c49e9cc1..a2937c03 100644
--- a/src/main/java/org/springframework/data/gemfire/config/annotation/EmbeddedManagerConfiguration.java
+++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EmbeddedManagerConfiguration.java
@@ -21,6 +21,7 @@ import java.util.Map;
import java.util.Properties;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
+import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
* The EmbeddedManagerConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
@@ -28,11 +29,14 @@ import org.springframework.data.gemfire.config.annotation.support.EmbeddedServic
* an embedded GemFire Manager.
*
* @author John Blum
- * @see EmbeddedServiceConfigurationSupport
+ * @see org.springframework.data.gemfire.config.annotation.EnableEmbeddedManager
+ * @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
*/
public class EmbeddedManagerConfiguration extends EmbeddedServiceConfigurationSupport {
+ protected static final int DEFAULT_JMX_MANAGER_PORT = 1099;
+
@Override
protected Class getAnnotationType() {
return EnableEmbeddedManager.class;
@@ -40,30 +44,30 @@ public class EmbeddedManagerConfiguration extends EmbeddedServiceConfigurationSu
@Override
protected Properties toGemFireProperties(Map annotationAttributes) {
- Properties gemfireProperties = new Properties();
+ PropertiesBuilder gemfireProperties = new PropertiesBuilder();
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"));
+ gemfireProperties.setProperty("jmx-manager", Boolean.TRUE.toString());
+ gemfireProperties.setProperty("jmx-manager-access-file", annotationAttributes.get("jmxManagerAccessFile"));
+ gemfireProperties.setProperty("jmx-manager-bind-address", annotationAttributes.get("jmxManagerBindAddress"));
+ gemfireProperties.setProperty("jmx-manager-hostname-for-clients", annotationAttributes.get("jmxManagerHostnameForClients"));
+ gemfireProperties.setProperty("jmx-manager-password-file", annotationAttributes.get("jmxManagerPasswordFile"));
+ gemfireProperties.setProperty("jmx-manager-port", resolvePort((Integer) annotationAttributes.get("jmxManagerPort"), DEFAULT_JMX_MANAGER_PORT));
+ gemfireProperties.setProperty("jmx-manager-start", annotationAttributes.get("jmxManagerStart"));
+ gemfireProperties.setProperty("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"));
+ gemfireProperties.setProperty("jmx-manager-ssl-enabled", Boolean.TRUE.toString());
+ gemfireProperties.setProperty("jmx-manager-ssl-ciphers", annotationAttributes.get("jmxManagerSslCiphers"));
+ gemfireProperties.setProperty("jmx-manager-ssl-protocols", annotationAttributes.get("jmxManagerSslProtocols"));
+ gemfireProperties.setProperty("jmx-manager-ssl-require-authentication", annotationAttributes.get("jmxManagerSslRequireAuthentication"));
}
}
- return gemfireProperties;
+ return gemfireProperties.build();
}
}
diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableEmbeddedLocator.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableEmbeddedLocator.java
index d5652d8f..3109cf2c 100644
--- a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableEmbeddedLocator.java
+++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableEmbeddedLocator.java
@@ -27,37 +27,36 @@ 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.
+ * The EnableEmbeddedLocator annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
+ * annotated class to start an embedded GemFire Locator service in this GemFire server/data node.
*
* @author John Blum
+ * @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.EmbeddedLocatorConfiguration
* @since 1.9.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
-@Documented
@Inherited
+@Documented
@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:
+ * Configures the host/IP address on which the embedded Locator service will bind to for accepting connections
+ * from clients sending Locator requests.
*
- * 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).
+ * Default is {@literal localhost}.
*/
- String startLocator() default "localhost[10334]";
+ String host() default EmbeddedLocatorConfiguration.DEFAULT_HOST;
+
+ /**
+ * Configures the port on which the embedded Locator service will bind to listening for client connections
+ * sending Locator requests.
+ *
+ * Default is {@literal 10334}.
+ */
+ int port() default EmbeddedLocatorConfiguration.DEFAULT_LOCATOR_PORT;
}
diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableEmbeddedManager.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableEmbeddedManager.java
index 41f18a21..b9c215d7 100644
--- a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableEmbeddedManager.java
+++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableEmbeddedManager.java
@@ -27,27 +27,28 @@ 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.
+ * The EnableEmbeddedManager annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
+ * annotated class to embed and start a GemFire Manager service in the GemFire server/data node.
*
* @author John Blum
+ * @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.EmbeddedManagerConfiguration
* @since 1.9.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
-@Documented
@Inherited
+@Documented
@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
+ * If {@literal 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 {@literal false} then all other jmx-manager-* properties
* are ignored.
*
- * Defaults to {@code true}.
+ * Defaults to {@literal true}.
*/
boolean jmxManager() default true;
@@ -64,46 +65,46 @@ public @interface EnableEmbeddedManager {
/**
* 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.
+ * non-HTTP connections. Ignored if JMX Manager is {@literal false} or {@literal jmx-manager-port} is zero.
*
* Defaults to {@literal localhost}.
*/
- String jmxManagerBindAddress() default "localhost";
+ String jmxManagerBindAddress() default "";
/**
* 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.
+ * {@literal jmx-manager} is {@literal false} or {@literal jmx-manager-port} is zero.
*
* Defaults to {@literal localhost}.
*/
- String jmxManagerHostnameForClients() default "localhost";
+ String jmxManagerHostnameForClients() default "";
/**
* 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.
+ * System property. Ignored if {@literal jmx-manager} is {@literal 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}.
+ * by the JVM for configuring access from remote JMX clients. Ignored if {@literal jmx-manager} is {@literal false}.
*
* Defaults to {@literal 1099}.
*/
- int jmxManagerPort() default 1099;
+ int jmxManagerPort() default EmbeddedManagerConfiguration.DEFAULT_JMX_MANAGER_PORT;
/**
- * Enables or disables SSL for connections to the JMX Manager. If {@code true} and {@literal jmx-manager-port}
+ * Enables or disables SSL for connections to the JMX Manager. If {@literal 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}.
+ * Defaults to {@literal false}.
*/
boolean jmxManagerSslEnabled() default false;
@@ -130,17 +131,17 @@ public @interface EnableEmbeddedManager {
* then GemFire uses the value of {@literal cluster-ssl-require-authentication} to determine whether JMX connections
* require authentication.
*
- * Defaults to {@code true}.
+ * Defaults to {@literal 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}.
+ * automatically be started when needed on a member that sets {@literal jmx-manager} to {@literal true}. Ignored if
+ * {@literal jmx-manager} is {@literal false}.
*
- * Defaults to {@code false}.
+ * Defaults to {@literal false}.
*/
boolean jmxManagerStart() default false;
@@ -149,7 +150,7 @@ public @interface EnableEmbeddedManager {
* 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}.
+ * Defaults to {@literal 2000}.
*/
int jmxManagerUpdateRate() default 2000;
diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableMemcachedServer.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableMemcachedServer.java
index 5f893d22..70037210 100644
--- a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableMemcachedServer.java
+++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableMemcachedServer.java
@@ -27,20 +27,21 @@ 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 EnableMemcachedServer annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
+ * annotated class to start an embedded Memcached Server (Gemcached) service in the GemFire server/data node.
*
- * The Gemcached service implements the Memcached server protocol enabling Memcached clients to connect and speak
- * to Pivotal GemFire or Apache Geode.
+ * The Gemcached service implements the Memcached Server protocol enabling Memcached clients to connect to
+ * and communicate with Pivotal GemFire or Apache Geode servers.
*
* @author John Blum
+ * @see org.springframework.context.annotation.Import
* @see org.springframework.data.gemfire.config.annotation.MemcachedServerConfiguration
* @since 1.9.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
-@Documented
@Inherited
+@Documented
@Import(MemcachedServerConfiguration.class)
@SuppressWarnings("unused")
public @interface EnableMemcachedServer {
@@ -51,7 +52,7 @@ public @interface EnableMemcachedServer {
*
* Default to {@literal 11211}.
*/
- int port() default 11211;
+ int port() default MemcachedServerConfiguration.DEFAULT_MEMCACHED_SERVER_PORT;
/**
* Sets the protocol used by an embedded Gemcached server. Valid values are BINARY and ASCII.
diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnablePdx.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnablePdx.java
index 00ce061b..c48d4bc1 100644
--- a/src/main/java/org/springframework/data/gemfire/config/annotation/EnablePdx.java
+++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnablePdx.java
@@ -25,26 +25,49 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * The EnablePdx class...
+ * The EnablePdx annotation marks a Spring {@link org.springframework.context.annotation.Configuration @Configuration}
+ * annotated class to enable the GemFire PDX features and functionality in a GemFire server/data node
+ * or GemFire cache client application.
*
* @author John Blum
- * @since 1.0.0
+ * @since 1.9.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
-@Documented
@Inherited
+@Documented
@SuppressWarnings("unused")
public @interface EnablePdx {
- String diskStoreName();
+ /**
+ * Configures the disk store that is used for PDX meta data.
+ */
+ String diskStoreName() default "";
+ /**
+ * Configures whether pdx ignores fields that were unread during deserialization.
+ *
+ * Default is {@literal false}.
+ */
boolean ignoreUnreadFields() default false;
+ /**
+ * Configures whether the type metadata for PDX objects is persisted to disk.
+ *
+ * Default is {@literal false}.
+ */
boolean persistent() default false;
+ /**
+ * Configures the object preference to {@link com.gemstone.gemfire.pdx.PdxInstance} type or {@link Object}.
+ *
+ * Default is {@literal false}.
+ */
boolean readSerialized() default false;
+ /**
+ * Configures the PDX serializer to be used by the cache to serialize object data.
+ */
String serializerBeanName() default "";
}
diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/MemcachedServerConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/MemcachedServerConfiguration.java
index 4d61550a..c92faded 100644
--- a/src/main/java/org/springframework/data/gemfire/config/annotation/MemcachedServerConfiguration.java
+++ b/src/main/java/org/springframework/data/gemfire/config/annotation/MemcachedServerConfiguration.java
@@ -21,6 +21,7 @@ import java.util.Map;
import java.util.Properties;
import org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport;
+import org.springframework.data.gemfire.util.PropertiesBuilder;
/**
* The MemcachedServerConfiguration class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
@@ -28,11 +29,14 @@ import org.springframework.data.gemfire.config.annotation.support.EmbeddedServic
* an embedded Memcached server.
*
* @author John Blum
+ * @see org.springframework.data.gemfire.config.annotation.EnableMemcachedServer
* @see org.springframework.data.gemfire.config.annotation.support.EmbeddedServiceConfigurationSupport
* @since 1.9.0
*/
public class MemcachedServerConfiguration extends EmbeddedServiceConfigurationSupport {
+ protected static final int DEFAULT_MEMCACHED_SERVER_PORT = 11211;
+
@Override
protected Class getAnnotationType() {
return EnableMemcachedServer.class;
@@ -40,11 +44,9 @@ public class MemcachedServerConfiguration extends EmbeddedServiceConfigurationSu
@Override
protected Properties toGemFireProperties(Map annotationAttributes) {
- Properties gemfireProperties = new Properties();
-
- setProperty(gemfireProperties, "memcached-port", annotationAttributes.get("port"));
- setProperty(gemfireProperties, "memcached-protocol", annotationAttributes.get("protocol"));
-
- return gemfireProperties;
+ return new PropertiesBuilder()
+ .setProperty("memcached-port", resolvePort((Integer) annotationAttributes.get("port"), DEFAULT_MEMCACHED_SERVER_PORT))
+ .setProperty("memcached-protocol", annotationAttributes.get("protocol"))
+ .build();
}
}
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 dde9e25a..bf7cd3dd 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
@@ -52,7 +52,7 @@ public @interface PeerCacheApplication {
/**
* Indicates whether the "copy on read" is enabled for this cache.
*
- * Default is {@code false}.
+ * Default is {@literal false}.
*/
boolean copyOnRead() default false;
@@ -68,7 +68,7 @@ public @interface PeerCacheApplication {
* after it has been forced out of the distributed system by a network partition event or has otherwise been
* shunned by other members. Use this property to enable the auto-reconnect behavior.
*
- * Default is {@code false}.
+ * Default is {@literal false}.
*/
boolean enableAutoReconnect() default false;
@@ -133,7 +133,7 @@ public @interface PeerCacheApplication {
* Configures whether this GemFire cache member node would pull it's configuration meta-data
* from the cluster-based Cluster Configuration service.
*
- * Default is {@code false}.
+ * Default is {@literal false}.
*/
boolean useClusterConfiguration() default false;
diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/support/EmbeddedServiceConfigurationSupport.java b/src/main/java/org/springframework/data/gemfire/config/annotation/support/EmbeddedServiceConfigurationSupport.java
index 2f79ebe3..9a882511 100644
--- a/src/main/java/org/springframework/data/gemfire/config/annotation/support/EmbeddedServiceConfigurationSupport.java
+++ b/src/main/java/org/springframework/data/gemfire/config/annotation/support/EmbeddedServiceConfigurationSupport.java
@@ -21,6 +21,7 @@ import java.util.Map;
import java.util.Properties;
import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -28,6 +29,7 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration;
import org.springframework.data.gemfire.util.CollectionUtils;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -42,42 +44,21 @@ import org.springframework.util.StringUtils;
*/
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());
- }
+ public static final String DEFAULT_HOST = "localhost";
- return properties;
+ @Autowired
+ @SuppressWarnings("all")
+ private AbstractCacheConfiguration cacheConfiguration;
+
+ /* (non-Javadoc) */
+ @SuppressWarnings("unchecked")
+ protected T cacheConfiguration() {
+ Assert.state(cacheConfiguration != null, "AbstractCacheConfiguration was not properly initialized");
+ return (T) this.cacheConfiguration;
}
/* (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 annotationAttributes =
- importingClassMetadata.getAnnotationAttributes(getAnnotationTypeName());
-
- Properties customizedGemFireProperties = toGemFireProperties(annotationAttributes);
-
- if (!CollectionUtils.isEmpty(customizedGemFireProperties)) {
- registerGemFirePropertiesBeanPostProcessor(registry, customizedGemFireProperties);
- }
- }
- }
+ protected abstract Class getAnnotationType();
/* (non-Javadoc) */
protected String getAnnotationTypeName() {
@@ -90,33 +71,70 @@ public abstract class EmbeddedServiceConfigurationSupport implements ImportBeanD
}
/* (non-Javadoc) */
- protected abstract Class getAnnotationType();
+ @Override
+ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
+ if (importingClassMetadata.hasAnnotation(getAnnotationTypeName())) {
+ Map annotationAttributes =
+ importingClassMetadata.getAnnotationAttributes(getAnnotationTypeName());
- /* (non-Javadoc) */
- protected String getBeanName() {
- return String.format("%1$s.%2$s", getClass().getName(), getAnnotationTypeSimpleName());
- }
+ Properties customGemFireProperties = toGemFireProperties(annotationAttributes);
- /* (non-Javadoc) */
- protected BeanDefinitionHolder newBeanDefinitionHolder(BeanDefinitionBuilder builder) {
- return new BeanDefinitionHolder(builder.getBeanDefinition(), getBeanName());
+ if (hasProperties(customGemFireProperties)) {
+ try {
+ cacheConfiguration().add(customGemFireProperties);
+ }
+ catch (Exception ignore) {
+ registerGemFirePropertiesBeanPostProcessor(registry, customGemFireProperties);
+ }
+ }
+ }
}
/* (non-Javadoc) */
protected abstract Properties toGemFireProperties(Map annotationAttributes);
+ /* (non-Javadoc) */
+ protected boolean hasProperties(Properties properties) {
+ return !CollectionUtils.isEmpty(properties);
+ }
+
/* (non-Javadoc) */
protected void registerGemFirePropertiesBeanPostProcessor(BeanDefinitionRegistry registry,
- Properties customizedGemFireProperties) {
+ Properties customGemFireProperties) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
GemFirePropertiesBeanPostProcessor.class);
- builder.addConstructorArgValue(customizedGemFireProperties);
+ builder.addConstructorArgValue(customGemFireProperties);
BeanDefinitionReaderUtils.registerBeanDefinition(newBeanDefinitionHolder(builder), registry);
}
+ /* (non-Javadoc) */
+ protected BeanDefinitionHolder newBeanDefinitionHolder(BeanDefinitionBuilder builder) {
+ return new BeanDefinitionHolder(builder.getBeanDefinition(), generateBeanName());
+ }
+
+ /* (non-Javadoc) */
+ protected String generateBeanName() {
+ return String.format("%1$s.%2$s", getClass().getName(), getAnnotationTypeSimpleName());
+ }
+
+ /* (non-Javadoc) */
+ protected String resolveHost(String hostname) {
+ return resolveHost(hostname, DEFAULT_HOST);
+ }
+
+ /* (non-Javadoc) */
+ protected String resolveHost(String hostname, String defaultHostname) {
+ return (StringUtils.hasText(hostname) ? hostname : defaultHostname);
+ }
+
+ /* (non-Javadoc) */
+ protected Integer resolvePort(Integer port, Integer defaultPort) {
+ return (port != null ? port : defaultPort);
+ }
+
/**
* Spring {@link BeanPostProcessor} used to post process before initialization in GemFire System properties
* Spring bean defined in the application context.
@@ -125,7 +143,7 @@ public abstract class EmbeddedServiceConfigurationSupport implements ImportBeanD
*/
protected static class GemFirePropertiesBeanPostProcessor implements BeanPostProcessor {
- static final String GEMFIRE_PROPERTIES_BEAN_NAME = "gemfireProperties";
+ protected static final String GEMFIRE_PROPERTIES_BEAN_NAME = "gemfireProperties";
private final Properties gemfireProperties;
diff --git a/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java b/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java
index 7ddc2e4d..93ac489a 100644
--- a/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java
+++ b/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java
@@ -1,11 +1,11 @@
/*
* Copyright 2002-2013 the original author or authors.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
@@ -117,5 +117,4 @@ public abstract class ArrayUtils {
return newArray;
}
-
}
diff --git a/src/main/java/org/springframework/data/gemfire/util/CacheUtils.java b/src/main/java/org/springframework/data/gemfire/util/CacheUtils.java
index 195e95d0..17c681ab 100644
--- a/src/main/java/org/springframework/data/gemfire/util/CacheUtils.java
+++ b/src/main/java/org/springframework/data/gemfire/util/CacheUtils.java
@@ -125,5 +125,4 @@ public abstract class CacheUtils extends DistributedSystemUtils {
return null;
}
}
-
}
diff --git a/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java b/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java
index f3f90c37..c5ee55ef 100644
--- a/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java
+++ b/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java
@@ -77,7 +77,7 @@ public abstract class CollectionUtils extends org.springframework.util.Collectio
* @return the given Collection if not null, otherwise return an empty Collection (List).
* @see java.util.Collections#emptyList()
*/
- public static Collection nullSafeCollection(final Collection collection) {
+ public static Collection nullSafeCollection(Collection collection) {
return (collection != null ? collection : Collections.emptyList());
}
@@ -100,15 +100,14 @@ public abstract class CollectionUtils extends org.springframework.util.Collectio
}
@Override public T next() {
- throw new NoSuchElementException("no elements in this Iterator");
+ throw new NoSuchElementException("No more elements");
}
@Override public void remove() {
- throw new UnsupportedOperationException("operation not supported");
+ throw new UnsupportedOperationException("Operation not supported");
}
};
}
});
}
-
}
diff --git a/src/main/java/org/springframework/data/gemfire/util/DistributedSystemUtils.java b/src/main/java/org/springframework/data/gemfire/util/DistributedSystemUtils.java
index c0982ca8..fe607ed2 100644
--- a/src/main/java/org/springframework/data/gemfire/util/DistributedSystemUtils.java
+++ b/src/main/java/org/springframework/data/gemfire/util/DistributedSystemUtils.java
@@ -18,9 +18,6 @@ package org.springframework.data.gemfire.util;
import java.util.Properties;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
import com.gemstone.gemfire.cache.GemFireCache;
import com.gemstone.gemfire.cache.server.CacheServer;
import com.gemstone.gemfire.distributed.DistributedSystem;
@@ -30,6 +27,9 @@ import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
import com.gemstone.gemfire.distributed.internal.InternalLocator;
import com.gemstone.gemfire.internal.DistributionLocator;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
/**
* DistributedSystemUtils is an abstract utility class for working with the GemFire DistributedSystem.
*
diff --git a/src/main/java/org/springframework/data/gemfire/util/PropertiesBuilder.java b/src/main/java/org/springframework/data/gemfire/util/PropertiesBuilder.java
new file mode 100644
index 00000000..db97c884
--- /dev/null
+++ b/src/main/java/org/springframework/data/gemfire/util/PropertiesBuilder.java
@@ -0,0 +1,119 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Properties;
+
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * The PropertiesBuilder class is a Builder for {@link java.util.Properties}.
+ *
+ * @author John Blum
+ * @see java.util.Properties
+ * @since 1.0.0
+ */
+@SuppressWarnings("unused")
+public class PropertiesBuilder {
+
+ private final Properties properties;
+
+ public PropertiesBuilder() {
+ this.properties = new Properties();
+ }
+
+ public PropertiesBuilder(Properties defaults) {
+ this.properties = new Properties(defaults);
+ }
+
+ public PropertiesBuilder(PropertiesBuilder builder) {
+ this(builder != null ? builder.build() : null);
+ }
+
+ public PropertiesBuilder add(Properties properties) {
+ if (!CollectionUtils.isEmpty(properties)) {
+ this.properties.putAll(properties);
+ }
+
+ return this;
+ }
+
+ public PropertiesBuilder add(PropertiesBuilder builder) {
+ if (builder != null) {
+ add(builder.build());
+ }
+
+ return this;
+ }
+
+ public PropertiesBuilder from(InputStream in) {
+ try {
+ this.properties.load(in);
+ return this;
+ }
+ catch (IOException e) {
+ throw new IllegalArgumentException("Failed to read properties from InputStream", e);
+ }
+ }
+
+ public PropertiesBuilder from(Reader reader) {
+ try {
+ this.properties.load(reader);
+ return this;
+ }
+ catch (IOException e) {
+ throw new IllegalArgumentException("Failed to read properties from Reader", e);
+ }
+ }
+
+ public PropertiesBuilder fromXml(InputStream xml) {
+ try {
+ this.properties.loadFromXML(xml);
+ return this;
+ }
+ catch (IOException e) {
+ throw new IllegalArgumentException("Failed to read properties from XML InputStream", e);
+ }
+ }
+
+ public PropertiesBuilder setProperty(String name, Object value) {
+ if (value != null) {
+ setProperty(name, value.toString());
+ }
+
+ return this;
+ }
+
+ public PropertiesBuilder setProperty(String name, String value) {
+ Assert.hasText(name, String.format("Name [%s] must not be null or empty", name));
+
+ if (StringUtils.hasText(value)) {
+ this.properties.setProperty(name, value);
+ }
+
+ return this;
+ }
+
+ public Properties build() {
+ return this.properties;
+ }
+}
diff --git a/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsTest.java b/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsTest.java
index 28f07e51..b3fa8a2a 100644
--- a/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsTest.java
+++ b/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsTest.java
@@ -148,18 +148,17 @@ public class CollectionUtilsTest {
iterator.next();
}
catch (NoSuchElementException ignore) {
- assertThat(ignore.getMessage(), is(equalTo("no elements in this Iterator")));
+ assertThat(ignore.getMessage(), is(equalTo("No more elements")));
assertThat(ignore.getCause(), is(nullValue()));
try {
iterator.remove();
}
catch (UnsupportedOperationException expected) {
- assertThat(expected.getMessage(), is(equalTo("operation not supported")));
+ assertThat(expected.getMessage(), is(equalTo("Operation not supported")));
assertThat(expected.getCause(), is(nullValue()));
throw expected;
}
}
}
-
}