diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java index e8d0545e9..d87d64395 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoDbFactoryParser.java @@ -15,15 +15,20 @@ */ package org.springframework.data.mongodb.config; -import static org.springframework.data.mongodb.config.BeanNames.*; -import static org.springframework.data.mongodb.config.ParsingUtils.*; +import static org.springframework.data.mongodb.config.BeanNames.DB_FACTORY; +import static org.springframework.data.mongodb.config.ParsingUtils.getSourceBeanDefinition; + +import java.util.Map; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.CustomEditorConfigurer; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.ManagedMap; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; @@ -60,7 +65,7 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser { String uri = element.getAttribute("uri"); String mongoRef = element.getAttribute("mongo-ref"); String dbname = element.getAttribute("dbname"); - BeanDefinition userCredentials = getUserCredentialsBeanDefinition(element, parserContext); + BeanDefinition userCredentials = getUserCredentialsBeanDefinition(element, parserContext); // Common setup BeanDefinitionBuilder dbFactoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(SimpleMongoDbFactory.class); @@ -85,6 +90,10 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser { if (userCredentials != null) { dbFactoryBuilder.addConstructorArgValue(userCredentials); } + + //Register property editor to parse WriteConcern + + registerWriteConcernPropertyEditor(parserContext.getRegistry()); return getSourceBeanDefinition(dbFactoryBuilder, parserContext, element); } @@ -106,6 +115,14 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser { return BeanDefinitionReaderUtils.registerWithGeneratedName(mongoBuilder.getBeanDefinition(), parserContext.getRegistry()); } + + private void registerWriteConcernPropertyEditor(BeanDefinitionRegistry registry) { + BeanDefinitionBuilder customEditorConfigurer = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class); + Map customEditors = new ManagedMap(); + customEditors.put("com.mongodb.WriteConcern", "org.springframework.data.mongodb.config.WriteConcernPropertyEditor"); + customEditorConfigurer.addPropertyValue("customEditors", customEditors); + BeanDefinitionReaderUtils.registerWithGeneratedName(customEditorConfigurer.getBeanDefinition(), registry); + } /** * Returns a {@link BeanDefinition} for a {@link UserCredentials} object. 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 9e76e5850..1f4958ebb 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 @@ -53,7 +53,8 @@ public class MongoParser extends AbstractSingleBeanDefinitionParser { ParsingUtils.parseMongoOptions(element, builder); ParsingUtils.parseReplicaSet(element, builder); - registerCustomEditorConfigurer(parserContext.getRegistry()); + registerServerAddressPropertyEditor(parserContext.getRegistry()); + registerWriteConcernPropertyEditor(parserContext.getRegistry()); } @@ -62,7 +63,7 @@ public class MongoParser extends AbstractSingleBeanDefinitionParser { * registering a 'default' property editor with the container. * @param parserContext the ParserContext to */ - private void registerCustomEditorConfigurer(BeanDefinitionRegistry registry) { + private void registerServerAddressPropertyEditor(BeanDefinitionRegistry registry) { BeanDefinitionBuilder customEditorConfigurer = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class); Map customEditors = new ManagedMap(); customEditors.put("java.util.List", "org.springframework.data.mongodb.config.ServerAddressPropertyEditor"); @@ -70,6 +71,14 @@ public class MongoParser extends AbstractSingleBeanDefinitionParser { BeanDefinitionReaderUtils.registerWithGeneratedName(customEditorConfigurer.getBeanDefinition(), registry); } + private void registerWriteConcernPropertyEditor(BeanDefinitionRegistry registry) { + BeanDefinitionBuilder customEditorConfigurer = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class); + Map customEditors = new ManagedMap(); + customEditors.put("com.mongodb.WriteConcern", "org.springframework.data.mongodb.config.WriteConcernPropertyEditor"); + customEditorConfigurer.addPropertyValue("customEditors", customEditors); + BeanDefinitionReaderUtils.registerWithGeneratedName(customEditorConfigurer.getBeanDefinition(), registry); + } + @Override protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/WriteConcernPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/WriteConcernPropertyEditor.java new file mode 100644 index 000000000..a04c85d86 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/WriteConcernPropertyEditor.java @@ -0,0 +1,53 @@ +/* + * Copyright 2011 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.mongodb.config; + +import java.beans.PropertyEditorSupport; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; + +import org.springframework.util.StringUtils; + +import com.mongodb.ServerAddress; +import com.mongodb.WriteConcern; + +/** + * Parse a string to a WriteConcern. If it is a well know String as identified by the WriteConcern.valueOf, use the + * well known WriteConcern value, otherwise pass the string as is to the constructor of the write concern. + * There is no support for other constructor signatures when parsing from a string value. + * + * @author Mark Pollack + * + */ +public class WriteConcernPropertyEditor extends PropertyEditorSupport { + + /** + * Parse a string to a List + */ + public void setAsText(String writeConcernString) { + + WriteConcern writeConcern = WriteConcern.valueOf(writeConcernString); + if (writeConcern != null) { + // have a well known string + setValue(writeConcern); + } else { + // pass on the string to the constructor + setValue(new WriteConcern(writeConcernString)); + } + + } +} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java index bb474ac70..3211ff7b7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java @@ -94,6 +94,10 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory { public void setWriteConcern(WriteConcern writeConcern) { this.writeConcern = writeConcern; } + + public WriteConcern getWriteConcern() { + return writeConcern; + } /* * (non-Javadoc) diff --git a/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-1.0.xsd b/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-1.0.xsd index 058066e01..b8d4d8d72 100644 --- a/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-1.0.xsd +++ b/spring-data-mongodb/src/main/resources/org/springframework/data/mongodb/config/spring-mongo-1.0.xsd @@ -93,7 +93,19 @@ The password to use when connecting to a MongoDB server. The Mongo URI string.]]> + + + + The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object + + + + + + + @@ -259,6 +271,18 @@ The name of the Mongo object that determines what server to monitor. (by default + + + + + + + + + + + + @@ -288,7 +314,19 @@ The Mongo driver options + + + + The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object + + + + + + + values = definition.getPropertyValues().getPropertyValueList(); - assertThat(values, hasItem(new PropertyValue("writeConcern", "SAFE"))); + assertThat(myDbFactoryWriteConcern, equalTo(myExpectedWriteConcern)); + assertThat(myDbWriteConcern, equalTo(myExpectedWriteConcern)); + assertThat(myDbWriteConcern, equalTo(myDbFactoryWriteConcern)); } + //This test will fail since equals in WriteConcern uses == for _w and not .equals + public void testWriteConcernEquality() { + String s1 = new String("rack1"); + String s2 = new String("rack1"); + WriteConcern wc1 = new WriteConcern(s1); + WriteConcern wc2 = new WriteConcern(s2); + assertThat(wc1, equalTo(wc2)); + } + + + @Test public void createsDbFactoryBean() { XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("namespace/db-factory-bean.xml")); @@ -64,7 +108,7 @@ public class MongoDbFactoryParserIntegrationTests { XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("namespace/db-factory-bean.xml")); Mongo mongo = factory.getBean(Mongo.class); - assertThat(mongo.getMongoOptions().maxAutoConnectRetryTime, is(27L)); + assertThat(mongo.getMongoOptions().maxAutoConnectRetryTime, is(27L)); } /** @@ -98,7 +142,7 @@ public class MongoDbFactoryParserIntegrationTests { MongoDbFactory dbFactory = factory.getBean("mongoDbFactory", MongoDbFactory.class); DB db = dbFactory.getDb(); - assertThat("database", is(db.getName())); + assertThat(db.getName(), is("database")); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MyWriteConcern.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MyWriteConcern.java new file mode 100644 index 000000000..0b98964e6 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MyWriteConcern.java @@ -0,0 +1,56 @@ +package org.springframework.data.mongodb.config; + +import com.mongodb.WriteConcern; + +public class MyWriteConcern { + + public MyWriteConcern(WriteConcern wc) { + this._w = wc.getWObject(); + this._continueOnErrorForInsert = wc.getContinueOnErrorForInsert(); + this._fsync = wc.getFsync(); + this._j = wc.getJ(); + this._wtimeout = wc.getWtimeout(); + } + + Object _w = 0; + int _wtimeout = 0; + boolean _fsync = false; + boolean _j = false; + boolean _continueOnErrorForInsert = false; + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (_continueOnErrorForInsert ? 1231 : 1237); + result = prime * result + (_fsync ? 1231 : 1237); + result = prime * result + (_j ? 1231 : 1237); + result = prime * result + ((_w == null) ? 0 : _w.hashCode()); + result = prime * result + _wtimeout; + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + MyWriteConcern other = (MyWriteConcern) obj; + if (_continueOnErrorForInsert != other._continueOnErrorForInsert) + return false; + if (_fsync != other._fsync) + return false; + if (_j != other._j) + return false; + if (_w == null) { + if (other._w != null) + return false; + } else if (!_w.equals(other._w)) + return false; + if (_wtimeout != other._wtimeout) + return false; + return true; + } + +} diff --git a/spring-data-mongodb/src/test/resources/namespace/db-factory-bean-custom-write-concern.xml b/spring-data-mongodb/src/test/resources/namespace/db-factory-bean-custom-write-concern.xml new file mode 100644 index 000000000..783ae2ff2 --- /dev/null +++ b/spring-data-mongodb/src/test/resources/namespace/db-factory-bean-custom-write-concern.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-mongodb/src/test/resources/namespace/db-factory-bean.xml b/spring-data-mongodb/src/test/resources/namespace/db-factory-bean.xml index a8ec95403..ea91e67f7 100644 --- a/spring-data-mongodb/src/test/resources/namespace/db-factory-bean.xml +++ b/spring-data-mongodb/src/test/resources/namespace/db-factory-bean.xml @@ -2,12 +2,23 @@ - + - + + + + \ No newline at end of file