From 213963f2fffe2b0eea62276ba5dbbf1818317fa1 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Fri, 12 Aug 2011 15:38:19 +0200 Subject: [PATCH] DATADOC-215 - Allow configuring a WriteConcern per MongoFactoryBean. Added ability to configure a WriteConcern for an entire MongoFactoryBean and exposed the attribute via the namespace. --- .../data/mongodb/config/MongoParser.java | 1 + .../data/mongodb/core/MongoFactoryBean.java | 105 +++++++++++------- .../mongodb/config/spring-mongo-1.0.xsd | 25 +++-- .../config/MongoParserIntegrationTests.java | 48 ++++++++ .../test/resources/namespace/mongo-bean.xml | 10 ++ 5 files changed, 136 insertions(+), 53 deletions(-) create mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoParserIntegrationTests.java create mode 100644 spring-data-mongodb/src/test/resources/namespace/mongo-bean.xml diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParser.java index fa3903e01..42c52bb56 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoParser.java @@ -43,6 +43,7 @@ public class MongoParser extends AbstractSingleBeanDefinitionParser { ParsingUtils.setPropertyValue(element, builder, "port", "port"); ParsingUtils.setPropertyValue(element, builder, "host", "host"); + ParsingUtils.setPropertyValue(element, builder, "write-concern", "writeConcern"); ParsingUtils.parseMongoOptions(parserContext, element, builder); ParsingUtils.parseReplicaSet(parserContext, element, builder); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoFactoryBean.java index ada0931f0..7d18d2472 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoFactoryBean.java @@ -18,36 +18,37 @@ package org.springframework.data.mongodb.core; import java.util.List; -import com.mongodb.Mongo; -import com.mongodb.MongoOptions; -import com.mongodb.ServerAddress; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.mongodb.CannotGetMongoDbConnectionException; -import org.springframework.util.Assert; + +import com.mongodb.Mongo; +import com.mongodb.MongoOptions; +import com.mongodb.ServerAddress; +import com.mongodb.WriteConcern; /** * Convenient factory for configuring MongoDB. * * @author Thomas Risberg * @author Graeme Rocher + * @author Oliver Gierke * @since 1.0 */ -public class MongoFactoryBean implements FactoryBean, InitializingBean, PersistenceExceptionTranslator { +public class MongoFactoryBean implements FactoryBean, PersistenceExceptionTranslator { /** * Logger, available to subclasses. */ protected final Log logger = LogFactory.getLog(getClass()); - private Mongo mongo; private MongoOptions mongoOptions; private String host; private Integer port; + private WriteConcern writeConcern; private List replicaSetSeeds; private List replicaPair; @@ -73,8 +74,13 @@ public class MongoFactoryBean implements FactoryBean, InitializingBean, P this.port = port; } - public PersistenceExceptionTranslator getExceptionTranslator() { - return exceptionTranslator; + /** + * Sets the {@link WriteConcern} to be configured for the {@link Mongo} instance to be created. + * + * @param writeConcern + */ + public void setWriteConcern(WriteConcern writeConcern) { + this.writeConcern = writeConcern; } public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) { @@ -82,49 +88,64 @@ public class MongoFactoryBean implements FactoryBean, InitializingBean, P } public Mongo getObject() throws Exception { - Assert.notNull(mongo, "Mongo must not be null"); + + Mongo mongo; + + if (host == null) { + + logger.warn("Property host not specified. Using default configuration"); + mongo = new Mongo(); + + } else { + + ServerAddress defaultOptions = new ServerAddress(); + + if (mongoOptions == null) { + mongoOptions = new MongoOptions(); + } + + if (replicaPair != null) { + if (replicaPair.size() < 2) { + throw new CannotGetMongoDbConnectionException("A replica pair must have two server entries"); + } + mongo = new Mongo(replicaPair.get(0), replicaPair.get(1), mongoOptions); + } else if (replicaSetSeeds != null) { + mongo = new Mongo(replicaSetSeeds, mongoOptions); + } else { + String mongoHost = host != null ? host : defaultOptions.getHost(); + mongo = port != null ? new Mongo(new ServerAddress(mongoHost, port), mongoOptions) : new Mongo(mongoHost, + mongoOptions); + } + } + + if (writeConcern != null) { + mongo.setWriteConcern(writeConcern); + } + return mongo; + } + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObjectType() + */ public Class getObjectType() { return Mongo.class; } + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#isSingleton() + */ public boolean isSingleton() { - return false; - } - - public void afterPropertiesSet() throws Exception { - // apply defaults - convenient when used to configure for tests - // in an application context - if (mongo == null) { - - if (host == null) { - logger.warn("Property host not specified. Using default configuration"); - mongo = new Mongo(); - } else { - ServerAddress defaultOptions = new ServerAddress(); - if (mongoOptions == null) - mongoOptions = new MongoOptions(); - if (replicaPair != null) { - if (replicaPair.size() < 2) { - throw new CannotGetMongoDbConnectionException("A replica pair must have two server entries"); - } - mongo = new Mongo(replicaPair.get(0), replicaPair.get(1), mongoOptions); - } else if (replicaSetSeeds != null) { - mongo = new Mongo(replicaSetSeeds, mongoOptions); - } else { - String mongoHost = host != null ? host : defaultOptions.getHost(); - if (port != null) { - mongo = new Mongo(new ServerAddress(mongoHost, port), mongoOptions); - } else { - mongo = new Mongo(mongoHost, mongoOptions); - } - } - } - } + return true; } + /* + * (non-Javadoc) + * @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException) + */ public DataAccessException translateExceptionIfPossible(RuntimeException ex) { return exceptionTranslator.translateExceptionIfPossible(ex); } diff --git a/spring-data-mongodb/src/main/resources/org/springframework/data/document/mongodb/config/spring-mongo-1.0.xsd b/spring-data-mongodb/src/main/resources/org/springframework/data/document/mongodb/config/spring-mongo-1.0.xsd index a75298e16..d87c36523 100644 --- a/spring-data-mongodb/src/main/resources/org/springframework/data/document/mongodb/config/spring-mongo-1.0.xsd +++ b/spring-data-mongodb/src/main/resources/org/springframework/data/document/mongodb/config/spring-mongo-1.0.xsd @@ -39,17 +39,6 @@ Defines a MongoDbFactory for connecting to a specific database ]]> - + + + + + + + + + + + + + @@ -267,6 +269,7 @@ The Mongo driver options + values = definition.getPropertyValues().getPropertyValueList(); + assertThat(values, hasItem(new PropertyValue("writeConcern", "SAFE"))); + + factory.getBean("mongo"); + } +} diff --git a/spring-data-mongodb/src/test/resources/namespace/mongo-bean.xml b/spring-data-mongodb/src/test/resources/namespace/mongo-bean.xml new file mode 100644 index 000000000..728428251 --- /dev/null +++ b/spring-data-mongodb/src/test/resources/namespace/mongo-bean.xml @@ -0,0 +1,10 @@ + + + + + +