DATAMONGO-319 - WriteConcern not parsed correctly in namespace handlers
DATAMONGO-311 - Update MongoDB driver to v 2.7.x
This commit is contained in:
@@ -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<String, String> customEditors = new ManagedMap<String, String>();
|
||||
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.
|
||||
|
||||
@@ -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<String, String> customEditors = new ManagedMap<String, String>();
|
||||
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<String, String> customEditors = new ManagedMap<String, String>();
|
||||
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 {
|
||||
|
||||
@@ -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<ServerAddress>
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -93,7 +93,19 @@ The password to use when connecting to a MongoDB server.
|
||||
The Mongo URI string.]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="write-concern">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<!-- MLP
|
||||
<xsd:attributeGroup ref="writeConcern" />
|
||||
-->
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
@@ -259,6 +271,18 @@ The name of the Mongo object that determines what server to monitor. (by default
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="writeConcernEnumeration">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="NONE" />
|
||||
<xsd:enumeration value="NORMAL" />
|
||||
<xsd:enumeration value="SAFE" />
|
||||
<xsd:enumeration value="FSYNC_SAFE" />
|
||||
<xsd:enumeration value="REPLICA_SAFE" />
|
||||
<xsd:enumeration value="JOURNAL_SAFE" />
|
||||
<xsd:enumeration value="MAJORITY" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
<!-- MLP
|
||||
<xsd:attributeGroup name="writeConcern">
|
||||
<xsd:attribute name="write-concern">
|
||||
<xsd:simpleType>
|
||||
@@ -268,11 +292,13 @@ The name of the Mongo object that determines what server to monitor. (by default
|
||||
<xsd:enumeration value="SAFE" />
|
||||
<xsd:enumeration value="FSYNC_SAFE" />
|
||||
<xsd:enumeration value="REPLICA_SAFE" />
|
||||
<xsd:enumeration value="JOURNAL_SAFE" />
|
||||
<xsd:enumeration value="MAJORITY" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
</xsd:attributeGroup>
|
||||
|
||||
-->
|
||||
<xsd:complexType name="mongoType">
|
||||
<xsd:sequence minOccurs="0" maxOccurs="1">
|
||||
<xsd:element name="options" type="optionsType">
|
||||
@@ -288,7 +314,19 @@ The Mongo driver options
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="write-concern">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<!-- MLP
|
||||
<xsd:attributeGroup ref="writeConcern" />
|
||||
-->
|
||||
<xsd:attribute name="id" type="xsd:ID" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.mongodb.config;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -27,12 +28,17 @@ import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.xml.XmlBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.MongoURI;
|
||||
import com.mongodb.WriteConcern;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MongoDbFactoryParser}.
|
||||
@@ -41,15 +47,53 @@ import com.mongodb.MongoURI;
|
||||
*/
|
||||
public class MongoDbFactoryParserIntegrationTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void parsesWriteConcern() {
|
||||
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("namespace/db-factory-bean.xml"));
|
||||
BeanDefinition definition = factory.getBeanDefinition("first");
|
||||
|
||||
List<PropertyValue> values = definition.getPropertyValues().getPropertyValueList();
|
||||
assertThat(values, hasItem(new PropertyValue("writeConcern", "SAFE")));
|
||||
public void testWriteConcern() throws Exception {
|
||||
SimpleMongoDbFactory dbFactory = new SimpleMongoDbFactory(new Mongo("localhost"), "database");
|
||||
dbFactory.setWriteConcern(WriteConcern.SAFE);
|
||||
DB db = dbFactory.getDb();
|
||||
assertThat(WriteConcern.SAFE, is(dbFactory.getWriteConcern()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parsesWriteConcern() {
|
||||
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("namespace/db-factory-bean.xml");
|
||||
assertWriteConcern(ctx, WriteConcern.SAFE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parsesCustomWriteConcern() {
|
||||
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("namespace/db-factory-bean-custom-write-concern.xml");
|
||||
assertWriteConcern(ctx, new WriteConcern("rack1"));
|
||||
}
|
||||
|
||||
private void assertWriteConcern(ClassPathXmlApplicationContext ctx, WriteConcern expectedWriteConcern) {
|
||||
SimpleMongoDbFactory dbFactory = ctx.getBean("first", SimpleMongoDbFactory.class);
|
||||
DB db = dbFactory.getDb();
|
||||
assertThat("db", is(db.getName()));
|
||||
|
||||
MyWriteConcern myDbFactoryWriteConcern = new MyWriteConcern(dbFactory.getWriteConcern());
|
||||
MyWriteConcern myDbWriteConcern = new MyWriteConcern(db.getWriteConcern());
|
||||
MyWriteConcern myExpectedWriteConcern = new MyWriteConcern(expectedWriteConcern);
|
||||
|
||||
|
||||
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"));
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<mongo:db-factory id="first" mongo-ref="mongo" write-concern="rack1" />
|
||||
|
||||
<mongo:mongo id="mongo">
|
||||
<mongo:options max-auto-connect-retry-time="27" />
|
||||
</mongo:mongo>
|
||||
|
||||
<!-- now part of the namespace
|
||||
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
|
||||
<property name="customEditors">
|
||||
<map>
|
||||
<entry key="com.mongodb.WriteConcern" value="org.springframework.data.mongodb.config.WriteConcernPropertyEditor"/>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
-->
|
||||
|
||||
</beans>
|
||||
@@ -2,12 +2,23 @@
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<mongo:db-factory id="first" write-concern="SAFE" mongo-ref="mongo" />
|
||||
<mongo:db-factory id="first" mongo-ref="mongo" write-concern="SAFE" />
|
||||
|
||||
<mongo:mongo id="mongo">
|
||||
<mongo:options max-auto-connect-retry-time="27" />
|
||||
</mongo:mongo>
|
||||
</beans>
|
||||
|
||||
<!-- now part of the namespace
|
||||
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
|
||||
<property name="customEditors">
|
||||
<map>
|
||||
<entry key="com.mongodb.WriteConcern" value="org.springframework.data.mongodb.config.WriteConcernPropertyEditor"/>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
-->
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user