Skip to content

Commit 6ac85c1

Browse files
author
Dave Syer
committed
Add username/password and MongoClientOptions to Mongo config
The username/password option stil lonly works for a single host (to connect to a cluster I suspect you need to set the URI). Also added a MongoClientOptions (if a bean of that type exists it will be used to populate the options that aren't in the URI). Fixed spring-projectsgh-536
1 parent 6cf946e commit 6ac85c1

File tree

6 files changed

+168
-20
lines changed

6 files changed

+168
-20
lines changed

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.context.annotation.Configuration;
3030

3131
import com.mongodb.Mongo;
32+
import com.mongodb.MongoClientOptions;
3233

3334
/**
3435
* {@link EnableAutoConfiguration Auto-configuration} for Mongo.
@@ -45,6 +46,9 @@ public class MongoAutoConfiguration {
4546
@Autowired
4647
private MongoProperties properties;
4748

49+
@Autowired(required = false)
50+
private MongoClientOptions options;
51+
4852
private Mongo mongo;
4953

5054
@PreDestroy
@@ -57,7 +61,7 @@ public void close() throws UnknownHostException {
5761
@Bean
5862
@ConditionalOnMissingBean
5963
public Mongo mongo() throws UnknownHostException {
60-
this.mongo = this.properties.createMongoClient();
64+
this.mongo = this.properties.createMongoClient(this.options);
6165
return this.mongo;
6266
}
6367

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoDataAutoConfiguration.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ public class MongoDataAutoConfiguration {
5252
@Autowired
5353
private MongoProperties properties;
5454

55+
@Bean
56+
@ConditionalOnMissingBean
57+
public MongoDbFactory mongoDbFactory(Mongo mongo) throws Exception {
58+
String db = this.properties.getMongoClientDatabase();
59+
return new SimpleMongoDbFactory(mongo, db);
60+
}
61+
5562
@Bean
5663
@ConditionalOnMissingBean
5764
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory)
@@ -61,18 +68,11 @@ public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory)
6168

6269
@Bean
6370
@ConditionalOnMissingBean
64-
public MongoDbFactory mongoDbFactory(Mongo mongo) throws Exception {
71+
public GridFsTemplate gridFsTemplate(Mongo mongo, MongoTemplate mongoTemplate) {
6572
String db = StringUtils.hasText(this.properties.getGridFsDatabase()) ? this.properties
6673
.getGridFsDatabase() : this.properties.getMongoClientDatabase();
67-
68-
return new SimpleMongoDbFactory(mongo, db);
69-
}
70-
71-
@Bean
72-
@ConditionalOnMissingBean
73-
public GridFsTemplate gridFsTemplate(MongoDbFactory mongoDbFactory,
74-
MongoTemplate mongoTemplate) {
75-
return new GridFsTemplate(mongoDbFactory, mongoTemplate.getConverter());
74+
return new GridFsTemplate(new SimpleMongoDbFactory(mongo, db),
75+
mongoTemplate.getConverter());
7676
}
7777

7878
}

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoProperties.java

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,18 @@
1717
package org.springframework.boot.autoconfigure.mongo;
1818

1919
import java.net.UnknownHostException;
20+
import java.util.Arrays;
21+
import java.util.List;
2022

2123
import org.springframework.boot.context.properties.ConfigurationProperties;
2224

2325
import com.mongodb.DBPort;
2426
import com.mongodb.MongoClient;
27+
import com.mongodb.MongoClientOptions;
28+
import com.mongodb.MongoClientOptions.Builder;
2529
import com.mongodb.MongoClientURI;
30+
import com.mongodb.MongoCredential;
31+
import com.mongodb.ServerAddress;
2632

2733
/**
2834
* Configuration properties for Mongo.
@@ -44,6 +50,10 @@ public class MongoProperties {
4450

4551
private String gridFsDatabase;
4652

53+
private String username;
54+
55+
private char[] password;
56+
4757
public String getHost() {
4858
return this.host;
4959
}
@@ -60,6 +70,31 @@ public void setDatabase(String database) {
6070
this.database = database;
6171
}
6272

73+
public String getUsername() {
74+
return this.username;
75+
}
76+
77+
public void setUsername(String username) {
78+
this.username = username;
79+
}
80+
81+
public char[] getPassword() {
82+
return this.password;
83+
}
84+
85+
public void setPassword(char[] password) {
86+
this.password = password;
87+
}
88+
89+
public void clearPassword() {
90+
if (this.password == null) {
91+
return;
92+
}
93+
for (int i = 0; i < this.password.length; i++) {
94+
this.password[i] = 0;
95+
}
96+
}
97+
6398
public String getUri() {
6499
return this.uri;
65100
}
@@ -91,11 +126,51 @@ public String getMongoClientDatabase() {
91126
return new MongoClientURI(this.uri).getDatabase();
92127
}
93128

94-
public MongoClient createMongoClient() throws UnknownHostException {
95-
if (this.host != null) {
96-
return new MongoClient(this.host, this.port);
129+
public MongoClient createMongoClient(MongoClientOptions options)
130+
throws UnknownHostException {
131+
try {
132+
if (this.host != null) {
133+
if (options == null) {
134+
options = MongoClientOptions.builder().build();
135+
}
136+
List<MongoCredential> credentials = null;
137+
if (this.password != null && this.username != null) {
138+
credentials = Arrays.asList(MongoCredential.createMongoCRCredential(
139+
this.username, getMongoClientDatabase(), this.password));
140+
}
141+
return new MongoClient(Arrays.asList(new ServerAddress(this.host,
142+
this.port)), credentials, options);
143+
}
144+
// The options and credentials are in the URI
145+
return new MongoClient(new MongoClientURI(this.uri, builder(options)));
146+
}
147+
finally {
148+
clearPassword();
149+
}
150+
}
151+
152+
private Builder builder(MongoClientOptions options) {
153+
Builder builder = MongoClientOptions.builder();
154+
if (options != null) {
155+
builder.alwaysUseMBeans(options.isAlwaysUseMBeans());
156+
builder.autoConnectRetry(options.isAutoConnectRetry());
157+
builder.connectionsPerHost(options.getConnectionsPerHost());
158+
builder.connectTimeout(options.getConnectTimeout());
159+
builder.cursorFinalizerEnabled(options.isCursorFinalizerEnabled());
160+
builder.dbDecoderFactory(options.getDbDecoderFactory());
161+
builder.dbEncoderFactory(options.getDbEncoderFactory());
162+
builder.description(options.getDescription());
163+
builder.maxAutoConnectRetryTime(options.getMaxAutoConnectRetryTime());
164+
builder.maxWaitTime(options.getMaxWaitTime());
165+
builder.readPreference(options.getReadPreference());
166+
builder.socketFactory(options.getSocketFactory());
167+
builder.socketKeepAlive(options.isSocketKeepAlive());
168+
builder.socketTimeout(options.getSocketTimeout());
169+
builder.threadsAllowedToBlockForConnectionMultiplier(options
170+
.getThreadsAllowedToBlockForConnectionMultiplier());
171+
builder.writeConcern(options.getWriteConcern());
97172
}
98-
return new MongoClient(new MongoClientURI(this.uri));
173+
return builder;
99174
}
100175

101176
}

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,13 @@
1919
import org.junit.After;
2020
import org.junit.Test;
2121
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
22+
import org.springframework.boot.test.EnvironmentTestUtils;
2223
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
23-
import org.springframework.data.mongodb.core.MongoTemplate;
24+
import org.springframework.context.annotation.Bean;
25+
import org.springframework.context.annotation.Configuration;
26+
27+
import com.mongodb.Mongo;
28+
import com.mongodb.MongoClientOptions;
2429

2530
import static org.junit.Assert.assertEquals;
2631

@@ -41,11 +46,44 @@ public void close() {
4146
}
4247

4348
@Test
44-
public void templateExists() {
49+
public void clientExists() {
4550
this.context = new AnnotationConfigApplicationContext(
46-
PropertyPlaceholderAutoConfiguration.class, MongoAutoConfiguration.class,
47-
MongoDataAutoConfiguration.class);
48-
assertEquals(1, this.context.getBeanNamesForType(MongoTemplate.class).length);
51+
PropertyPlaceholderAutoConfiguration.class, MongoAutoConfiguration.class);
52+
assertEquals(1, this.context.getBeanNamesForType(Mongo.class).length);
53+
}
54+
55+
@Test
56+
public void optionsAdded() {
57+
this.context = new AnnotationConfigApplicationContext();
58+
EnvironmentTestUtils.addEnvironment(this.context,
59+
"spring.data.mongodb.host:localhost");
60+
this.context.register(OptionsConfig.class,
61+
PropertyPlaceholderAutoConfiguration.class, MongoAutoConfiguration.class);
62+
this.context.refresh();
63+
assertEquals(300, this.context.getBean(Mongo.class).getMongoOptions()
64+
.getSocketTimeout());
65+
}
66+
67+
@Test
68+
public void optionsAddedButNoHost() {
69+
this.context = new AnnotationConfigApplicationContext();
70+
EnvironmentTestUtils.addEnvironment(this.context,
71+
"spring.data.mongodb.uri:mongodb://localhost/test");
72+
this.context.register(OptionsConfig.class,
73+
PropertyPlaceholderAutoConfiguration.class, MongoAutoConfiguration.class);
74+
this.context.refresh();
75+
assertEquals(300, this.context.getBean(Mongo.class).getMongoOptions()
76+
.getSocketTimeout());
77+
}
78+
79+
@Configuration
80+
protected static class OptionsConfig {
81+
82+
@Bean
83+
public MongoClientOptions mongoOptions() {
84+
return MongoClientOptions.builder().socketTimeout(300).build();
85+
}
86+
4987
}
5088

5189
}

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoDataAutoConfigurationTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
import org.junit.After;
2020
import org.junit.Test;
2121
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
22+
import org.springframework.boot.test.EnvironmentTestUtils;
2223
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
24+
import org.springframework.data.mongodb.core.MongoTemplate;
2325
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
2426

2527
import static org.junit.Assert.assertEquals;
@@ -45,6 +47,18 @@ public void templateExists() {
4547
this.context = new AnnotationConfigApplicationContext(
4648
PropertyPlaceholderAutoConfiguration.class, MongoAutoConfiguration.class,
4749
MongoDataAutoConfiguration.class);
50+
assertEquals(1, this.context.getBeanNamesForType(MongoTemplate.class).length);
51+
}
52+
53+
@Test
54+
public void gridFsTemplateExists() {
55+
this.context = new AnnotationConfigApplicationContext();
56+
EnvironmentTestUtils.addEnvironment(this.context,
57+
"spring.data.mongodb.gridFsDatabase:grid");
58+
this.context.register(PropertyPlaceholderAutoConfiguration.class,
59+
MongoAutoConfiguration.class, MongoDataAutoConfiguration.class);
60+
this.context.refresh();
4861
assertEquals(1, this.context.getBeanNamesForType(GridFsTemplate.class).length);
4962
}
63+
5064
}

spring-boot/src/test/java/org/springframework/boot/bind/RelaxedDataBinderTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ public void testBindString() throws Exception {
7474
assertEquals("bar", target.getFoo());
7575
}
7676

77+
@Test
78+
public void testBindChars() throws Exception {
79+
VanillaTarget target = new VanillaTarget();
80+
bind(target, "bar: foo");
81+
assertEquals("foo", new String(target.getBar()));
82+
}
83+
7784
@Test
7885
public void testBindStringWithPrefix() throws Exception {
7986
VanillaTarget target = new VanillaTarget();
@@ -656,12 +663,22 @@ public static class VanillaTarget {
656663

657664
private String foo;
658665

666+
private char[] bar;
667+
659668
private int value;
660669

661670
private String foo_bar;
662671

663672
private String fooBaz;
664673

674+
public char[] getBar() {
675+
return this.bar;
676+
}
677+
678+
public void setBar(char[] bar) {
679+
this.bar = bar;
680+
}
681+
665682
public int getValue() {
666683
return this.value;
667684
}

0 commit comments

Comments
 (0)