Permalink
Browse files

Reconfigure Redis

- Abstract common Mongo and Redis config code into base class

- Replace a single RedisConnectionFactory with one connecting to a redis cloud
service bound to the current application

- Extract existing post-processor test into separate tests

Change-Id: Icca0b4a0d325d1ee9c8e987c0c06c2b0426655db
  • Loading branch information...
Jennifer Hickey
Jennifer Hickey committed Sep 13, 2011
1 parent 0f1e902 commit e867dff4f32a9e7fbfe801e72c08f61edb471e7d
Showing with 896 additions and 458 deletions.
  1. +7 −0 auto-reconfiguration/auto-reconfiguration-core/pom.xml
  2. +75 −0 ...econfiguration-core/src/main/java/org/cloudfoundry/reconfiguration/AbstractServiceConfigurer.java
  3. +13 −2 ...core/src/main/java/org/cloudfoundry/reconfiguration/CloudAutoStagingBeanFactoryPostProcessor.java
  4. +16 −60 ...figuration-core/src/main/java/org/cloudfoundry/reconfiguration/data/document/MongoConfigurer.java
  5. +43 −0 ...figuration-core/src/main/java/org/cloudfoundry/reconfiguration/data/keyvalue/RedisConfigurer.java
  6. +5 −5 ...nfiguration-core/src/main/java/org/cloudfoundry/reconfiguration/data/orm/HibernateConfigurer.java
  7. +5 −5 ...o-reconfiguration-core/src/main/java/org/cloudfoundry/reconfiguration/data/orm/JpaConfigurer.java
  8. +17 −13 ...ion-core/src/main/java/org/cloudfoundry/reconfiguration/data/relational/DataSourceConfigurer.java
  9. +114 −0 .../src/test/java/org/cloudfoundry/reconfiguration/CloudAutoStagingBeanFactoryPostProcessorTest.java
  10. +38 −0 ...onfiguration-core/src/test/java/org/cloudfoundry/reconfiguration/CloudEnvironmentMockingTest.java
  11. +0 −337 ...st/java/org/cloudfoundry/reconfiguration/CloudFactoryAutoStagingBeanFactoryPostProcessorTest.java
  12. +26 −15 ...ration-core/src/test/java/org/cloudfoundry/reconfiguration/data/document/MongoConfigurerTest.java
  13. +137 −0 ...ration-core/src/test/java/org/cloudfoundry/reconfiguration/data/keyvalue/RedisConfigurerTest.java
  14. +116 −0 ...uration-core/src/test/java/org/cloudfoundry/reconfiguration/data/orm/HibernateConfigurerTest.java
  15. +83 −0 ...configuration-core/src/test/java/org/cloudfoundry/reconfiguration/data/orm/JpaConfigurerTest.java
  16. +117 −0 ...core/src/test/java/org/cloudfoundry/reconfiguration/data/relational/DataSourceConfigurerTest.java
  17. +19 −0 ...src/test/resources/org/cloudfoundry/reconfiguration/data/keyvalue/test-multiple-redis-context.xml
  18. +13 −0 ...ion-core/src/test/resources/org/cloudfoundry/reconfiguration/data/keyvalue/test-redis-context.xml
  19. 0 ...-core/src/test/resources/org/cloudfoundry/reconfiguration/{ → data/orm}/hibernate.test.properties
  20. +1 −2 ...ources/org/cloudfoundry/reconfiguration/{ → data/orm}/test-grails-embedded-props-good-context.xml
  21. +1 −2 ...sources/org/cloudfoundry/reconfiguration/{ → data/orm}/test-grails-map-reference-good-context.xml
  22. +2 −3 ...cloudfoundry/reconfiguration/{ → data/orm}/test-grails-propertyFactory-reference-good-context.xml
  23. +1 −1 ...src/test/resources/org/cloudfoundry/reconfiguration/{ → data/orm}/test-hibernate-good-context.xml
  24. +3 −3 ...-core/src/test/resources/org/cloudfoundry/reconfiguration/{ → data/orm}/test-jpa-good-context.xml
  25. +3 −3 ...sources/org/cloudfoundry/reconfiguration/{ → data/orm}/test-jpa-typedStringValue-good-context.xml
  26. +2 −3 ...econfiguration/{ → data/orm}/test-propertyFactory-nested-reference-list-location-good-context.xml
  27. +2 −3 ...onfiguration/{ → data/orm}/test-propertyFactory-nested-reference-single-location-good-context.xml
  28. +20 −0 ...core/src/test/resources/org/cloudfoundry/reconfiguration/data/relational/test-ds-good-context.xml
  29. +12 −1 vcap-java-test-app/src/main/java/org/cloudfoundry/test/ServiceController.java
  30. +5 −0 vcap-java-test-app/src/main/resources/META-INF/spring/root-context.xml
@@ -15,6 +15,7 @@
<properties>
<spring-data-mongo.version>1.0.0.M4</spring-data-mongo.version>
<spring.version>2.5.6</spring.version>
+ <spring-data-redis.version>1.0.0.M4</spring-data-redis.version>
</properties>
<dependencies>
<dependency>
@@ -151,6 +152,12 @@
<version>2.5</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-redis</artifactId>
+ <version>${spring-data-redis.version}</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<build>
<plugins>
@@ -0,0 +1,75 @@
+package org.cloudfoundry.reconfiguration;
+
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.cloudfoundry.runtime.env.CloudServiceException;
+import org.cloudfoundry.runtime.service.AbstractServiceCreator;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+
+abstract public class AbstractServiceConfigurer<SC extends AbstractServiceCreator<?,?>> implements Configurer {
+
+ private final Logger logger = Logger.getLogger(getClass().getName());
+
+ protected List<Map<String,Object>> cloudServices;
+
+ protected SC serviceCreator;
+
+ public AbstractServiceConfigurer(List<Map<String,Object>> cloudServices, SC serviceCreator) {
+ this.cloudServices = cloudServices;
+ this.serviceCreator = serviceCreator;
+ }
+
+ public boolean configure(DefaultListableBeanFactory beanFactory) {
+ Class<?> beanClass = loadClass(getBeanClass());
+ if(beanClass == null) {
+ logger.log(Level.INFO, "Class " + getBeanClass() + " not found. Skipping autostaging.");
+ return false;
+ }
+ String[] beanNames = beanFactory.getBeanNamesForType(beanClass);
+ if (beanNames.length == 0) {
+ logger.log(Level.INFO, "No beans of type " + getBeanClass() + " found in application context");
+ return false;
+ } else if (beanNames.length > 1) {
+ logger.log(Level.INFO, "More than 1 (" + beanNames.length
+ + ") beans of type " + getBeanClass() + "found in application context. Skipping autostaging.");
+ return false;
+ }
+ for (Map<String, Object> service : cloudServices) {
+ String label = (String) service.get("label");
+ if (label == null) {
+ continue;
+ }
+ if (label.startsWith(getServiceLabel())) {
+ try {
+ beanFactory.registerSingleton(getServiceBeanName(),
+ serviceCreator.createSingletonService().service);
+ beanFactory.removeBeanDefinition(beanNames[0]);
+ beanFactory.registerAlias(getServiceBeanName(), beanNames[0]);
+ return true;
+ } catch (CloudServiceException ex) {
+ logger.log(Level.INFO, "Error creating cloud service. Skipping autostaging", ex);
+ return false;
+ }
+ }
+ }
+ logger.log(Level.INFO, "No services found. Skipping autostaging");
+ return false;
+ }
+
+ abstract public String getServiceLabel();
+
+ abstract public String getBeanClass();
+
+ abstract public String getServiceBeanName();
+
+ protected Class<?> loadClass(String name) {
+ try {
+ return Class.forName(name);
+ } catch (Throwable ex) {
+ return null;
+ }
+ }
+}
@@ -4,15 +4,21 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sql.DataSource;
import org.cloudfoundry.reconfiguration.data.document.MongoConfigurer;
+import org.cloudfoundry.reconfiguration.data.keyvalue.RedisConfigurer;
import org.cloudfoundry.reconfiguration.data.relational.DataSourceConfigurer;
import org.cloudfoundry.runtime.env.CloudEnvironment;
+import org.cloudfoundry.runtime.service.document.MongoServiceCreator;
+import org.cloudfoundry.runtime.service.keyvalue.RedisServiceCreator;
+import org.cloudfoundry.runtime.service.relational.MysqlServiceCreator;
+import org.cloudfoundry.runtime.service.relational.PostgresqlServiceCreator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@@ -64,8 +70,13 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
} else {
cloudEnvironment = new CloudEnvironment();
}
- new DataSourceConfigurer(cloudEnvironment).configure( defaultListableBeanFactory);
- new MongoConfigurer(cloudEnvironment).configure(defaultListableBeanFactory);
+ final List<Map<String, Object>> cloudServices = cloudEnvironment.getServices();
+ new DataSourceConfigurer(cloudServices, new PostgresqlServiceCreator(cloudEnvironment),
+ new MysqlServiceCreator(cloudEnvironment)).configure(defaultListableBeanFactory);
+ new MongoConfigurer(cloudServices, new MongoServiceCreator(cloudEnvironment))
+ .configure(defaultListableBeanFactory);
+ new RedisConfigurer(cloudServices, new RedisServiceCreator(cloudEnvironment))
+ .configure(defaultListableBeanFactory);
}
/**
@@ -1,87 +1,43 @@
package org.cloudfoundry.reconfiguration.data.document;
+import java.util.List;
import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.cloudfoundry.reconfiguration.Configurer;
-import org.cloudfoundry.runtime.env.CloudEnvironment;
-import org.cloudfoundry.runtime.env.CloudServiceException;
+import org.cloudfoundry.reconfiguration.AbstractServiceConfigurer;
import org.cloudfoundry.runtime.service.document.MongoServiceCreator;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.data.mongodb.MongoDbFactory;
/**
- * Implementation of {@link Configurer} that replaces a single
+ * Implementation of {@link AbstractServiceConfigurer} that replaces a single
* {@link MongoDbFactory} with one connecting to a mongo cloud service bound to
* the current application.
*
* @author Jennifer Hickey
*
*/
-public class MongoConfigurer implements Configurer {
-
- private final Logger logger = Logger.getLogger(MongoConfigurer.class.getName());
+public class MongoConfigurer extends AbstractServiceConfigurer<MongoServiceCreator> {
static final String CF_MONGO_DB_FACTORY_NAME = "__cloudFoundryMongoDbFactory";
private static final String MONGO_DB_FACTORY_CLASS_NAME = "org.springframework.data.mongodb.MongoDbFactory";
- private CloudEnvironment cloudEnvironment;
-
- private MongoServiceCreator serviceCreator;
-
- public MongoConfigurer(CloudEnvironment cloudEnvironment) {
- this.cloudEnvironment = cloudEnvironment;
- this.serviceCreator = new MongoServiceCreator(cloudEnvironment);
+ public MongoConfigurer(List<Map<String, Object>> cloudServices, MongoServiceCreator serviceCreator) {
+ super(cloudServices, serviceCreator);
}
@Override
- public boolean configure(DefaultListableBeanFactory beanFactory) {
- Class<?> mongoDbFactoryClass = loadClass(MONGO_DB_FACTORY_CLASS_NAME);
- if (mongoDbFactoryClass == null) {
- logger.log(Level.INFO, "No MongoDbFactory class found.");
- return false;
- }
- String[] mongoDbFactoryBeanNames = beanFactory.getBeanNamesForType(mongoDbFactoryClass);
- if (mongoDbFactoryBeanNames.length == 0) {
- logger.log(Level.INFO, "No MongoDbFactory found in application context");
- return false;
- } else if (mongoDbFactoryBeanNames.length > 1) {
- logger.log(Level.INFO, "More than 1 (" + mongoDbFactoryBeanNames.length
- + ") MongoDbFactory beans found in application context. Skipping autostaging.");
- return false;
- }
- for (Map<String, Object> service : cloudEnvironment.getServices()) {
- String label = (String) service.get("label");
- if (label == null) {
- continue;
- }
- if (label.startsWith("mongodb")) {
- try {
- beanFactory.registerSingleton(CF_MONGO_DB_FACTORY_NAME,
- serviceCreator.createSingletonService().service);
- beanFactory.removeBeanDefinition(mongoDbFactoryBeanNames[0]);
- beanFactory.registerAlias(CF_MONGO_DB_FACTORY_NAME, mongoDbFactoryBeanNames[0]);
- return true;
- } catch (CloudServiceException ex) {
- logger.log(Level.INFO, "Multiple mongo services found. Skipping autostaging", ex);
- return false;
- }
- }
- }
- logger.log(Level.INFO, "No mongo service found. Skipping autostaging");
- return false;
+ public String getServiceLabel() {
+ return "mongodb";
}
- private Class<?> loadClass(String name) {
- try {
- return Class.forName(name);
- } catch (Throwable ex) {
- return null;
- }
+ @Override
+ public String getBeanClass() {
+ return MONGO_DB_FACTORY_CLASS_NAME;
}
- public void setServiceCreator(MongoServiceCreator serviceCreator) {
- this.serviceCreator = serviceCreator;
+ @Override
+ public String getServiceBeanName() {
+ return CF_MONGO_DB_FACTORY_NAME;
}
+
}
@@ -0,0 +1,43 @@
+package org.cloudfoundry.reconfiguration.data.keyvalue;
+
+import java.util.List;
+import java.util.Map;
+
+import org.cloudfoundry.reconfiguration.AbstractServiceConfigurer;
+import org.cloudfoundry.runtime.service.keyvalue.RedisServiceCreator;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+
+/**
+ * Implementation of {@link AbstractServiceConfigurer} that replaces a single
+ * {@link RedisConnectionFactory} with one connecting to a redis cloud service
+ * bound to the current application.
+ *
+ * @author Jennifer Hickey
+ *
+ */
+public class RedisConfigurer extends AbstractServiceConfigurer<RedisServiceCreator> {
+
+ private static final String CF_REDIS_CONN_FACTORY_NAME = "__cloudFoundryRedisConnectionFactory";
+
+ private static final String REDIS_CONN_FACTORY_CLASS_NAME = "org.springframework.data.redis.connection.RedisConnectionFactory";
+
+ public RedisConfigurer(List<Map<String, Object>> cloudServices, RedisServiceCreator serviceCreator) {
+ super(cloudServices, serviceCreator);
+ }
+
+ @Override
+ public String getServiceLabel() {
+ return "redis";
+ }
+
+ @Override
+ public String getBeanClass() {
+ return REDIS_CONN_FACTORY_CLASS_NAME;
+ }
+
+ @Override
+ public String getServiceBeanName() {
+ return CF_REDIS_CONN_FACTORY_NAME;
+ }
+
+}
@@ -3,11 +3,11 @@
*/
package org.cloudfoundry.reconfiguration.data.orm;
+import java.util.List;
import java.util.Map;
import org.cloudfoundry.reconfiguration.Configurer;
import org.cloudfoundry.reconfiguration.PropertyReplacer;
-import org.cloudfoundry.runtime.env.CloudEnvironment;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
/**
@@ -28,15 +28,15 @@
private PropertyReplacer propertyReplacer = new PropertyReplacer();
- private CloudEnvironment cloudEnvironment;
+ private List<Map<String,Object>> cloudServices;
- public HibernateConfigurer(CloudEnvironment cloudEnvironment) {
- this.cloudEnvironment = cloudEnvironment;
+ public HibernateConfigurer(List<Map<String,Object>> cloudServices) {
+ this.cloudServices = cloudServices;
}
public boolean configure(DefaultListableBeanFactory beanFactory) {
boolean configured = false;
- for (Map<String, Object> service : cloudEnvironment.getServices()) {
+ for (Map<String, Object> service : cloudServices) {
String label = (String) service.get("label");
if (label == null) {
continue;
@@ -3,11 +3,11 @@
*/
package org.cloudfoundry.reconfiguration.data.orm;
+import java.util.List;
import java.util.Map;
import org.cloudfoundry.reconfiguration.Configurer;
import org.cloudfoundry.reconfiguration.PropertyReplacer;
-import org.cloudfoundry.runtime.env.CloudEnvironment;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
/**
@@ -28,15 +28,15 @@
private PropertyReplacer propertyReplacer = new PropertyReplacer();
- private CloudEnvironment cloudEnvironment;
+ private List<Map<String,Object>> cloudServices;
- public JpaConfigurer(CloudEnvironment cloudEnvironment) {
- this.cloudEnvironment = cloudEnvironment;
+ public JpaConfigurer(List<Map<String,Object>> cloudServices) {
+ this.cloudServices = cloudServices;
}
public boolean configure(DefaultListableBeanFactory beanFactory) {
boolean configured = false;
- for (Map<String, Object> service : cloudEnvironment.getServices()) {
+ for (Map<String, Object> service : cloudServices) {
String label = (String) service.get("label");
if (label == null) {
Oops, something went wrong.

0 comments on commit e867dff

Please sign in to comment.