Skip to content

Commit 4f57712

Browse files
Thomas Darimontodrotbohm
Thomas Darimont
authored andcommitted
DATAMONGO-693 - More robust handling of host and replica set config in MongoFactoryBean.
MongoFactoryBean now considers empty strings for the replicaPair property as not set at all. The ServerAdressPropertyEditor also returns null as value for empty text strings. Deprecated setter for replica pair on MongoFactoryBean.
1 parent 478396c commit 4f57712

File tree

4 files changed

+83
-9
lines changed

4 files changed

+83
-9
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ServerAddressPropertyEditor.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011 the original author or authors.
2+
* Copyright 2011-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@
3131
*
3232
* @author Mark Pollack
3333
* @author Oliver Gierke
34+
* @author Thomas Darimont
3435
*/
3536
public class ServerAddressPropertyEditor extends PropertyEditorSupport {
3637

@@ -43,6 +44,11 @@ public class ServerAddressPropertyEditor extends PropertyEditorSupport {
4344
@Override
4445
public void setAsText(String replicaSetString) {
4546

47+
if (!StringUtils.hasText(replicaSetString)) {
48+
setValue(null);
49+
return;
50+
}
51+
4652
String[] replicaSetStringArray = StringUtils.commaDelimitedListToStringArray(replicaSetString);
4753
Set<ServerAddress> serverAddresses = new HashSet<ServerAddress>(replicaSetStringArray.length);
4854

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoFactoryBean.java

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
*/
1616
package org.springframework.data.mongodb.core;
1717

18-
import java.util.Arrays;
18+
import java.util.ArrayList;
19+
import java.util.Collection;
20+
import java.util.Collections;
1921
import java.util.List;
2022

2123
import org.springframework.beans.factory.DisposableBean;
@@ -24,6 +26,7 @@
2426
import org.springframework.dao.DataAccessException;
2527
import org.springframework.dao.support.PersistenceExceptionTranslator;
2628
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
29+
import org.springframework.util.StringUtils;
2730

2831
import com.mongodb.Mongo;
2932
import com.mongodb.MongoOptions;
@@ -36,6 +39,7 @@
3639
* @author Thomas Risberg
3740
* @author Graeme Rocher
3841
* @author Oliver Gierke
42+
* @author Thomas Darimont
3943
* @since 1.0
4044
*/
4145
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, DisposableBean,
@@ -57,11 +61,38 @@ public void setMongoOptions(MongoOptions mongoOptions) {
5761
}
5862

5963
public void setReplicaSetSeeds(ServerAddress[] replicaSetSeeds) {
60-
this.replicaSetSeeds = Arrays.asList(replicaSetSeeds);
64+
this.replicaSetSeeds = filterNonNullElementsAsList(replicaSetSeeds);
6165
}
6266

67+
/**
68+
* @deprecated use {@link #setReplicaSetSeeds(ServerAddress[])} instead
69+
*
70+
* @param replicaPair
71+
*/
72+
@Deprecated
6373
public void setReplicaPair(ServerAddress[] replicaPair) {
64-
this.replicaPair = Arrays.asList(replicaPair);
74+
this.replicaPair = filterNonNullElementsAsList(replicaPair);
75+
}
76+
77+
/**
78+
* @param elements the elements to filter <T>
79+
* @return a new unmodifiable {@link List#} from the given elements without nulls
80+
*/
81+
private <T> List<T> filterNonNullElementsAsList(T[] elements) {
82+
83+
if (elements == null) {
84+
return Collections.emptyList();
85+
}
86+
87+
List<T> candidateElements = new ArrayList<T>();
88+
89+
for (T element : elements) {
90+
if (element != null) {
91+
candidateElements.add(element);
92+
}
93+
}
94+
95+
return Collections.unmodifiableList(candidateElements);
6596
}
6697

6798
public void setHost(String host) {
@@ -127,15 +158,15 @@ public void afterPropertiesSet() throws Exception {
127158
mongoOptions = new MongoOptions();
128159
}
129160

130-
if (replicaPair != null) {
161+
if (!isNullOrEmpty(replicaPair)) {
131162
if (replicaPair.size() < 2) {
132163
throw new CannotGetMongoDbConnectionException("A replica pair must have two server entries");
133164
}
134165
mongo = new Mongo(replicaPair.get(0), replicaPair.get(1), mongoOptions);
135-
} else if (replicaSetSeeds != null) {
166+
} else if (!isNullOrEmpty(replicaSetSeeds)) {
136167
mongo = new Mongo(replicaSetSeeds, mongoOptions);
137168
} else {
138-
String mongoHost = host != null ? host : defaultOptions.getHost();
169+
String mongoHost = StringUtils.hasText(host) ? host : defaultOptions.getHost();
139170
mongo = port != null ? new Mongo(new ServerAddress(mongoHost, port), mongoOptions) : new Mongo(mongoHost,
140171
mongoOptions);
141172
}
@@ -147,6 +178,10 @@ public void afterPropertiesSet() throws Exception {
147178
this.mongo = mongo;
148179
}
149180

181+
private boolean isNullOrEmpty(Collection<?> elements) {
182+
return elements == null || elements.isEmpty();
183+
}
184+
150185
/*
151186
* (non-Javadoc)
152187
* @see org.springframework.beans.factory.DisposableBean#destroy()

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/ServerAddressPropertyEditorUnitTests.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012 the original author or authors.
2+
* Copyright 2012-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@
3131
* Unit tests for {@link ServerAddressPropertyEditor}.
3232
*
3333
* @author Oliver Gierke
34+
* @author Thomas Darimont
3435
*/
3536
public class ServerAddressPropertyEditorUnitTests {
3637

@@ -70,6 +71,16 @@ public void handlesEmptyAddressAsParseError() throws UnknownHostException {
7071
assertSingleAddressOfLocalhost(editor.getValue());
7172
}
7273

74+
/**
75+
* @see DATAMONGO-693
76+
*/
77+
@Test
78+
public void interpretEmptyStringAsNull() {
79+
80+
editor.setAsText("");
81+
assertNull(editor.getValue());
82+
}
83+
7384
private static void assertSingleAddressOfLocalhost(Object result) throws UnknownHostException {
7485

7586
assertThat(result, is(instanceOf(ServerAddress[].class)));

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoFactoryBeanIntegrationTest.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012 the original author or authors.
2+
* Copyright 2012-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,15 +21,19 @@
2121
import org.junit.Test;
2222
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
2323
import org.springframework.beans.factory.support.RootBeanDefinition;
24+
import org.springframework.data.mongodb.config.ServerAddressPropertyEditor;
2425
import org.springframework.data.mongodb.config.WriteConcernPropertyEditor;
2526
import org.springframework.test.util.ReflectionTestUtils;
2627

28+
import com.mongodb.Mongo;
29+
import com.mongodb.ServerAddress;
2730
import com.mongodb.WriteConcern;
2831

2932
/**
3033
* Integration tests for {@link MongoFactoryBean}.
3134
*
3235
* @author Oliver Gierke
36+
* @author Thomas Darimont
3337
*/
3438
public class MongoFactoryBeanIntegrationTest {
3539

@@ -49,4 +53,22 @@ public void convertsWriteConcernCorrectly() {
4953
MongoFactoryBean bean = factory.getBean("&factory", MongoFactoryBean.class);
5054
assertThat(ReflectionTestUtils.getField(bean, "writeConcern"), is((Object) WriteConcern.SAFE));
5155
}
56+
57+
/**
58+
* @see DATAMONGO-693
59+
*/
60+
@Test
61+
public void createMongoInstanceWithHostAndEmptyReplicaSets() {
62+
63+
RootBeanDefinition definition = new RootBeanDefinition(MongoFactoryBean.class);
64+
definition.getPropertyValues().addPropertyValue("host", "localhost");
65+
definition.getPropertyValues().addPropertyValue("replicaPair", "");
66+
67+
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
68+
factory.registerCustomEditor(ServerAddress.class, ServerAddressPropertyEditor.class);
69+
factory.registerBeanDefinition("factory", definition);
70+
71+
Mongo mongo = factory.getBean(Mongo.class);
72+
assertNotNull(mongo);
73+
}
5274
}

0 commit comments

Comments
 (0)