Skip to content

Commit 2ef33dc

Browse files
wilkinsonamhalbritterphilwebb
committed
Add ConnectionDetail support to Mongo auto-configuration
Update Mongo auto-configuration so that `MongoConnectionDetails` beans may be optionally used to provide connection details. See gh-34657 Co-Authored-By: Mortitz Halbritter <[email protected]> Co-Authored-By: Phillip Webb <[email protected]>
1 parent 042f0c8 commit 2ef33dc

13 files changed

+418
-49
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2023 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.
@@ -18,9 +18,12 @@
1818

1919
import com.mongodb.client.MongoClient;
2020

21+
import org.springframework.beans.factory.ObjectProvider;
2122
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2223
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
24+
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
2325
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
26+
import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails;
2427
import org.springframework.context.annotation.Bean;
2528
import org.springframework.context.annotation.Configuration;
2629
import org.springframework.data.mongodb.MongoDatabaseFactory;
@@ -32,15 +35,21 @@
3235
*
3336
* @author Andy Wilkinson
3437
* @author Stephane Nicoll
38+
* @author Moritz Halbritter
39+
* @author Phillip Webb
3540
*/
3641
@Configuration(proxyBeanMethods = false)
3742
@ConditionalOnMissingBean(MongoDatabaseFactory.class)
3843
@ConditionalOnSingleCandidate(MongoClient.class)
3944
class MongoDatabaseFactoryConfiguration {
4045

4146
@Bean
42-
MongoDatabaseFactorySupport<?> mongoDatabaseFactory(MongoClient mongoClient, MongoProperties properties) {
43-
return new SimpleMongoClientDatabaseFactory(mongoClient, properties.getMongoClientDatabase());
47+
MongoDatabaseFactorySupport<?> mongoDatabaseFactory(MongoClient mongoClient, MongoProperties properties,
48+
ObjectProvider<MongoConnectionDetails> connectionDetails) {
49+
return new SimpleMongoClientDatabaseFactory(mongoClient,
50+
connectionDetails.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties))
51+
.getConnectionString()
52+
.getDatabase());
4453
}
4554

4655
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.java

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2023 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.
@@ -20,10 +20,14 @@
2020
import com.mongodb.client.ClientSession;
2121
import com.mongodb.client.MongoDatabase;
2222

23+
import org.springframework.beans.factory.ObjectProvider;
2324
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2425
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
26+
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
27+
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails.GridFs;
2528
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
2629
import org.springframework.boot.autoconfigure.mongo.MongoProperties.Gridfs;
30+
import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails;
2731
import org.springframework.context.annotation.Bean;
2832
import org.springframework.context.annotation.Configuration;
2933
import org.springframework.dao.DataAccessException;
@@ -46,17 +50,13 @@
4650
* Configuration for Mongo-related beans that depend on a {@link MongoDatabaseFactory}.
4751
*
4852
* @author Andy Wilkinson
53+
* @author Moritz Halbritter
54+
* @author Phillip Webb
4955
*/
5056
@Configuration(proxyBeanMethods = false)
5157
@ConditionalOnBean(MongoDatabaseFactory.class)
5258
class MongoDatabaseFactoryDependentConfiguration {
5359

54-
private final MongoProperties properties;
55-
56-
MongoDatabaseFactoryDependentConfiguration(MongoProperties properties) {
57-
this.properties = properties;
58-
}
59-
6060
@Bean
6161
@ConditionalOnMissingBean(MongoOperations.class)
6262
MongoTemplate mongoTemplate(MongoDatabaseFactory factory, MongoConverter converter) {
@@ -75,31 +75,36 @@ MappingMongoConverter mappingMongoConverter(MongoDatabaseFactory factory, MongoM
7575

7676
@Bean
7777
@ConditionalOnMissingBean(GridFsOperations.class)
78-
GridFsTemplate gridFsTemplate(MongoDatabaseFactory factory, MongoTemplate mongoTemplate) {
79-
return new GridFsTemplate(new GridFsMongoDatabaseFactory(factory, this.properties),
80-
mongoTemplate.getConverter(), this.properties.getGridfs().getBucket());
78+
GridFsTemplate gridFsTemplate(MongoProperties properties, MongoDatabaseFactory factory, MongoTemplate mongoTemplate,
79+
ObjectProvider<MongoConnectionDetails> connectionDetailsProvider) {
80+
MongoConnectionDetails connectionDetails = connectionDetailsProvider
81+
.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties));
82+
return new GridFsTemplate(new GridFsMongoDatabaseFactory(factory, connectionDetails),
83+
mongoTemplate.getConverter(),
84+
(connectionDetails.getGridFs() != null) ? connectionDetails.getGridFs().getBucket() : null);
8185
}
8286

8387
/**
84-
* {@link MongoDatabaseFactory} decorator to respect {@link Gridfs#getDatabase()} if
85-
* set.
88+
* {@link MongoDatabaseFactory} decorator to respect {@link Gridfs#getDatabase()} or
89+
* {@link GridFs#getGridFs()} from the {@link MongoConnectionDetails} if set.
8690
*/
8791
static class GridFsMongoDatabaseFactory implements MongoDatabaseFactory {
8892

8993
private final MongoDatabaseFactory mongoDatabaseFactory;
9094

91-
private final MongoProperties properties;
95+
private final MongoConnectionDetails connectionDetails;
9296

93-
GridFsMongoDatabaseFactory(MongoDatabaseFactory mongoDatabaseFactory, MongoProperties properties) {
97+
GridFsMongoDatabaseFactory(MongoDatabaseFactory mongoDatabaseFactory,
98+
MongoConnectionDetails connectionDetails) {
9499
Assert.notNull(mongoDatabaseFactory, "MongoDatabaseFactory must not be null");
95-
Assert.notNull(properties, "Properties must not be null");
100+
Assert.notNull(connectionDetails, "ConnectionDetails must not be null");
96101
this.mongoDatabaseFactory = mongoDatabaseFactory;
97-
this.properties = properties;
102+
this.connectionDetails = connectionDetails;
98103
}
99104

100105
@Override
101106
public MongoDatabase getMongoDatabase() throws DataAccessException {
102-
String gridFsDatabase = this.properties.getGridfs().getDatabase();
107+
String gridFsDatabase = getGridFsDatabase(this.connectionDetails);
103108
if (StringUtils.hasText(gridFsDatabase)) {
104109
return this.mongoDatabaseFactory.getMongoDatabase(gridFsDatabase);
105110
}
@@ -126,6 +131,10 @@ public MongoDatabaseFactory withSession(ClientSession session) {
126131
return this.mongoDatabaseFactory.withSession(session);
127132
}
128133

134+
private String getGridFsDatabase(MongoConnectionDetails connectionDetails) {
135+
return (connectionDetails.getGridFs() != null) ? connectionDetails.getGridFs().getDatabase() : null;
136+
}
137+
129138
}
130139

131140
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 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.
@@ -26,14 +26,17 @@
2626
import org.bson.codecs.configuration.CodecRegistry;
2727
import reactor.core.publisher.Mono;
2828

29+
import org.springframework.beans.factory.ObjectProvider;
2930
import org.springframework.boot.autoconfigure.AutoConfiguration;
3031
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
3132
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
3233
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3334
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
35+
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
36+
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails.GridFs;
3437
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
35-
import org.springframework.boot.autoconfigure.mongo.MongoProperties.Gridfs;
3638
import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration;
39+
import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails;
3740
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3841
import org.springframework.context.annotation.Bean;
3942
import org.springframework.context.annotation.Import;
@@ -60,12 +63,12 @@
6063
* <p>
6164
* Registers a {@link ReactiveMongoTemplate} bean if no other bean of the same type is
6265
* configured.
63-
* <p>
64-
* Honors the {@literal spring.data.mongodb.database} property if set, otherwise connects
65-
* to the {@literal test} database.
6666
*
6767
* @author Mark Paluch
6868
* @author Artsiom Yudovin
69+
* @author Moritz Halbritter
70+
* @author Andy Wilkinson
71+
* @author Phillip Webb
6972
* @since 2.0.0
7073
*/
7174
@AutoConfiguration(after = MongoReactiveAutoConfiguration.class)
@@ -75,12 +78,19 @@
7578
@Import(MongoDataConfiguration.class)
7679
public class MongoReactiveDataAutoConfiguration {
7780

81+
private final MongoConnectionDetails connectionDetails;
82+
83+
MongoReactiveDataAutoConfiguration(MongoProperties properties,
84+
ObjectProvider<MongoConnectionDetails> connectionDetails) {
85+
this.connectionDetails = connectionDetails
86+
.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties));
87+
}
88+
7889
@Bean
7990
@ConditionalOnMissingBean(ReactiveMongoDatabaseFactory.class)
80-
public SimpleReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory(MongoProperties properties,
81-
MongoClient mongo) {
82-
String database = properties.getMongoClientDatabase();
83-
return new SimpleReactiveMongoDatabaseFactory(mongo, database);
91+
public SimpleReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory(MongoClient mongo) {
92+
return new SimpleReactiveMongoDatabaseFactory(mongo,
93+
this.connectionDetails.getConnectionString().getDatabase());
8494
}
8595

8696
@Bean
@@ -108,26 +118,27 @@ public DefaultDataBufferFactory dataBufferFactory() {
108118
@Bean
109119
@ConditionalOnMissingBean(ReactiveGridFsOperations.class)
110120
public ReactiveGridFsTemplate reactiveGridFsTemplate(ReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory,
111-
MappingMongoConverter mappingMongoConverter, DataBufferFactory dataBufferFactory,
112-
MongoProperties properties) {
121+
MappingMongoConverter mappingMongoConverter, DataBufferFactory dataBufferFactory) {
113122
return new ReactiveGridFsTemplate(dataBufferFactory,
114-
new GridFsReactiveMongoDatabaseFactory(reactiveMongoDatabaseFactory, properties), mappingMongoConverter,
115-
properties.getGridfs().getBucket());
123+
new GridFsReactiveMongoDatabaseFactory(reactiveMongoDatabaseFactory, this.connectionDetails),
124+
mappingMongoConverter,
125+
(this.connectionDetails.getGridFs() != null) ? this.connectionDetails.getGridFs().getBucket() : null);
116126
}
117127

118128
/**
119-
* {@link ReactiveMongoDatabaseFactory} decorator to use {@link Gridfs#getDatabase()}
120-
* when set.
129+
* {@link ReactiveMongoDatabaseFactory} decorator to use {@link GridFs#getGridFs()}
130+
* from the {@link MongoConnectionDetails} when set.
121131
*/
122132
static class GridFsReactiveMongoDatabaseFactory implements ReactiveMongoDatabaseFactory {
123133

124134
private final ReactiveMongoDatabaseFactory delegate;
125135

126-
private final MongoProperties properties;
136+
private final MongoConnectionDetails connectionDetails;
127137

128-
GridFsReactiveMongoDatabaseFactory(ReactiveMongoDatabaseFactory delegate, MongoProperties properties) {
138+
GridFsReactiveMongoDatabaseFactory(ReactiveMongoDatabaseFactory delegate,
139+
MongoConnectionDetails connectionDetails) {
129140
this.delegate = delegate;
130-
this.properties = properties;
141+
this.connectionDetails = connectionDetails;
131142
}
132143

133144
@Override
@@ -137,13 +148,17 @@ public boolean hasCodecFor(Class<?> type) {
137148

138149
@Override
139150
public Mono<MongoDatabase> getMongoDatabase() throws DataAccessException {
140-
String gridFsDatabase = this.properties.getGridfs().getDatabase();
151+
String gridFsDatabase = getGridFsDatabase(this.connectionDetails);
141152
if (StringUtils.hasText(gridFsDatabase)) {
142153
return this.delegate.getMongoDatabase(gridFsDatabase);
143154
}
144155
return this.delegate.getMongoDatabase();
145156
}
146157

158+
private String getGridFsDatabase(MongoConnectionDetails connectionDetails) {
159+
return (connectionDetails.getGridFs() != null) ? connectionDetails.getGridFs().getDatabase() : null;
160+
}
161+
147162
@Override
148163
public Mono<MongoDatabase> getMongoDatabase(String dbName) throws DataAccessException {
149164
return this.delegate.getMongoDatabase(dbName);

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,12 @@ MongoClientSettings mongoClientSettings() {
6262
}
6363

6464
@Bean
65-
MongoPropertiesClientSettingsBuilderCustomizer mongoPropertiesCustomizer(MongoProperties properties) {
66-
return new MongoPropertiesClientSettingsBuilderCustomizer(properties);
65+
StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties,
66+
ObjectProvider<MongoConnectionDetails> connectionDetailsProvider) {
67+
MongoConnectionDetails connectionDetails = connectionDetailsProvider
68+
.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties));
69+
return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails.getConnectionString(),
70+
properties.getUuidRepresentation());
6771
}
6872

6973
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright 2012-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.mongo;
18+
19+
import com.mongodb.ConnectionString;
20+
21+
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
22+
23+
/**
24+
* Details required to establish a connection to a MongoDB service.
25+
*
26+
* @author Moritz Halbritter
27+
* @author Andy Wilkinson
28+
* @author Phillip Webb
29+
* @since 3.1.0
30+
*/
31+
public interface MongoConnectionDetails extends ConnectionDetails {
32+
33+
/**
34+
* The {@link ConnectionString} for MongoDB.
35+
* @return the connection string
36+
*/
37+
ConnectionString getConnectionString();
38+
39+
/**
40+
* GridFS configuration.
41+
* @return the GridFS configuration or {@code null}
42+
*/
43+
default GridFs getGridFs() {
44+
return null;
45+
}
46+
47+
/**
48+
* GridFS configuration.
49+
*/
50+
interface GridFs {
51+
52+
/**
53+
* GridFS database name.
54+
* @return the GridFS database name or {@code null}
55+
*/
56+
String getDatabase();
57+
58+
/**
59+
* GridFS bucket name.
60+
* @return the GridFS bucket name or {@code null}
61+
*/
62+
String getBucket();
63+
64+
/**
65+
* Factory method to create a new {@link GridFs} instance.
66+
* @param database the database
67+
* @param bucket the bucket name
68+
* @return a new {@link GridFs} instance
69+
*/
70+
static GridFs of(String database, String bucket) {
71+
return new GridFs() {
72+
73+
@Override
74+
public String getDatabase() {
75+
return database;
76+
}
77+
78+
@Override
79+
public String getBucket() {
80+
return bucket;
81+
}
82+
83+
};
84+
}
85+
86+
}
87+
88+
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 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.
@@ -34,7 +34,10 @@
3434
* @author Scott Frederick
3535
* @author Safeer Ansari
3636
* @since 2.4.0
37+
* @deprecated since 3.1.0 in favor of
38+
* {@link StandardMongoClientSettingsBuilderCustomizer}
3739
*/
40+
@Deprecated(since = "3.1.0", forRemoval = true)
3841
public class MongoPropertiesClientSettingsBuilderCustomizer implements MongoClientSettingsBuilderCustomizer, Ordered {
3942

4043
private final MongoProperties properties;

0 commit comments

Comments
 (0)