diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java index 544bfcc17f..17f054ce56 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 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. @@ -18,9 +18,12 @@ package org.springframework.boot.autoconfigure.data.mongo; import com.mongodb.client.MongoClient; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; +import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; import org.springframework.boot.autoconfigure.mongo.MongoProperties; +import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.MongoDatabaseFactory; @@ -32,6 +35,8 @@ import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; * * @author Andy Wilkinson * @author Stephane Nicoll + * @author Moritz Halbritter + * @author Phillip Webb */ @Configuration(proxyBeanMethods = false) @ConditionalOnMissingBean(MongoDatabaseFactory.class) @@ -39,8 +44,12 @@ import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; class MongoDatabaseFactoryConfiguration { @Bean - MongoDatabaseFactorySupport mongoDatabaseFactory(MongoClient mongoClient, MongoProperties properties) { - return new SimpleMongoClientDatabaseFactory(mongoClient, properties.getMongoClientDatabase()); + MongoDatabaseFactorySupport mongoDatabaseFactory(MongoClient mongoClient, MongoProperties properties, + ObjectProvider connectionDetails) { + return new SimpleMongoClientDatabaseFactory(mongoClient, + connectionDetails.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties)) + .getConnectionString() + .getDatabase()); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.java index 9639b743b3..e82c6fb570 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 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. @@ -20,10 +20,14 @@ import com.mongodb.ClientSessionOptions; import com.mongodb.client.ClientSession; import com.mongodb.client.MongoDatabase; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; +import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails.GridFs; import org.springframework.boot.autoconfigure.mongo.MongoProperties; import org.springframework.boot.autoconfigure.mongo.MongoProperties.Gridfs; +import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.dao.DataAccessException; @@ -46,17 +50,13 @@ import org.springframework.util.StringUtils; * Configuration for Mongo-related beans that depend on a {@link MongoDatabaseFactory}. * * @author Andy Wilkinson + * @author Moritz Halbritter + * @author Phillip Webb */ @Configuration(proxyBeanMethods = false) @ConditionalOnBean(MongoDatabaseFactory.class) class MongoDatabaseFactoryDependentConfiguration { - private final MongoProperties properties; - - MongoDatabaseFactoryDependentConfiguration(MongoProperties properties) { - this.properties = properties; - } - @Bean @ConditionalOnMissingBean(MongoOperations.class) MongoTemplate mongoTemplate(MongoDatabaseFactory factory, MongoConverter converter) { @@ -75,31 +75,36 @@ class MongoDatabaseFactoryDependentConfiguration { @Bean @ConditionalOnMissingBean(GridFsOperations.class) - GridFsTemplate gridFsTemplate(MongoDatabaseFactory factory, MongoTemplate mongoTemplate) { - return new GridFsTemplate(new GridFsMongoDatabaseFactory(factory, this.properties), - mongoTemplate.getConverter(), this.properties.getGridfs().getBucket()); + GridFsTemplate gridFsTemplate(MongoProperties properties, MongoDatabaseFactory factory, MongoTemplate mongoTemplate, + ObjectProvider connectionDetailsProvider) { + MongoConnectionDetails connectionDetails = connectionDetailsProvider + .getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties)); + return new GridFsTemplate(new GridFsMongoDatabaseFactory(factory, connectionDetails), + mongoTemplate.getConverter(), + (connectionDetails.getGridFs() != null) ? connectionDetails.getGridFs().getBucket() : null); } /** - * {@link MongoDatabaseFactory} decorator to respect {@link Gridfs#getDatabase()} if - * set. + * {@link MongoDatabaseFactory} decorator to respect {@link Gridfs#getDatabase()} or + * {@link GridFs#getGridFs()} from the {@link MongoConnectionDetails} if set. */ static class GridFsMongoDatabaseFactory implements MongoDatabaseFactory { private final MongoDatabaseFactory mongoDatabaseFactory; - private final MongoProperties properties; + private final MongoConnectionDetails connectionDetails; - GridFsMongoDatabaseFactory(MongoDatabaseFactory mongoDatabaseFactory, MongoProperties properties) { + GridFsMongoDatabaseFactory(MongoDatabaseFactory mongoDatabaseFactory, + MongoConnectionDetails connectionDetails) { Assert.notNull(mongoDatabaseFactory, "MongoDatabaseFactory must not be null"); - Assert.notNull(properties, "Properties must not be null"); + Assert.notNull(connectionDetails, "ConnectionDetails must not be null"); this.mongoDatabaseFactory = mongoDatabaseFactory; - this.properties = properties; + this.connectionDetails = connectionDetails; } @Override public MongoDatabase getMongoDatabase() throws DataAccessException { - String gridFsDatabase = this.properties.getGridfs().getDatabase(); + String gridFsDatabase = getGridFsDatabase(this.connectionDetails); if (StringUtils.hasText(gridFsDatabase)) { return this.mongoDatabaseFactory.getMongoDatabase(gridFsDatabase); } @@ -126,6 +131,10 @@ class MongoDatabaseFactoryDependentConfiguration { return this.mongoDatabaseFactory.withSession(session); } + private String getGridFsDatabase(MongoConnectionDetails connectionDetails) { + return (connectionDetails.getGridFs() != null) ? connectionDetails.getGridFs().getDatabase() : null; + } + } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java index 332d5fb6d5..742270adc4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 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. @@ -26,14 +26,17 @@ import org.bson.codecs.Codec; import org.bson.codecs.configuration.CodecRegistry; import reactor.core.publisher.Mono; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; +import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails.GridFs; import org.springframework.boot.autoconfigure.mongo.MongoProperties; -import org.springframework.boot.autoconfigure.mongo.MongoProperties.Gridfs; import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; @@ -60,12 +63,12 @@ import org.springframework.util.StringUtils; *

* Registers a {@link ReactiveMongoTemplate} bean if no other bean of the same type is * configured. - *

- * Honors the {@literal spring.data.mongodb.database} property if set, otherwise connects - * to the {@literal test} database. * * @author Mark Paluch * @author Artsiom Yudovin + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb * @since 2.0.0 */ @AutoConfiguration(after = MongoReactiveAutoConfiguration.class) @@ -75,12 +78,19 @@ import org.springframework.util.StringUtils; @Import(MongoDataConfiguration.class) public class MongoReactiveDataAutoConfiguration { + private final MongoConnectionDetails connectionDetails; + + MongoReactiveDataAutoConfiguration(MongoProperties properties, + ObjectProvider connectionDetails) { + this.connectionDetails = connectionDetails + .getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties)); + } + @Bean @ConditionalOnMissingBean(ReactiveMongoDatabaseFactory.class) - public SimpleReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory(MongoProperties properties, - MongoClient mongo) { - String database = properties.getMongoClientDatabase(); - return new SimpleReactiveMongoDatabaseFactory(mongo, database); + public SimpleReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory(MongoClient mongo) { + return new SimpleReactiveMongoDatabaseFactory(mongo, + this.connectionDetails.getConnectionString().getDatabase()); } @Bean @@ -108,26 +118,27 @@ public class MongoReactiveDataAutoConfiguration { @Bean @ConditionalOnMissingBean(ReactiveGridFsOperations.class) public ReactiveGridFsTemplate reactiveGridFsTemplate(ReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory, - MappingMongoConverter mappingMongoConverter, DataBufferFactory dataBufferFactory, - MongoProperties properties) { + MappingMongoConverter mappingMongoConverter, DataBufferFactory dataBufferFactory) { return new ReactiveGridFsTemplate(dataBufferFactory, - new GridFsReactiveMongoDatabaseFactory(reactiveMongoDatabaseFactory, properties), mappingMongoConverter, - properties.getGridfs().getBucket()); + new GridFsReactiveMongoDatabaseFactory(reactiveMongoDatabaseFactory, this.connectionDetails), + mappingMongoConverter, + (this.connectionDetails.getGridFs() != null) ? this.connectionDetails.getGridFs().getBucket() : null); } /** - * {@link ReactiveMongoDatabaseFactory} decorator to use {@link Gridfs#getDatabase()} - * when set. + * {@link ReactiveMongoDatabaseFactory} decorator to use {@link GridFs#getGridFs()} + * from the {@link MongoConnectionDetails} when set. */ static class GridFsReactiveMongoDatabaseFactory implements ReactiveMongoDatabaseFactory { private final ReactiveMongoDatabaseFactory delegate; - private final MongoProperties properties; + private final MongoConnectionDetails connectionDetails; - GridFsReactiveMongoDatabaseFactory(ReactiveMongoDatabaseFactory delegate, MongoProperties properties) { + GridFsReactiveMongoDatabaseFactory(ReactiveMongoDatabaseFactory delegate, + MongoConnectionDetails connectionDetails) { this.delegate = delegate; - this.properties = properties; + this.connectionDetails = connectionDetails; } @Override @@ -137,13 +148,17 @@ public class MongoReactiveDataAutoConfiguration { @Override public Mono getMongoDatabase() throws DataAccessException { - String gridFsDatabase = this.properties.getGridfs().getDatabase(); + String gridFsDatabase = getGridFsDatabase(this.connectionDetails); if (StringUtils.hasText(gridFsDatabase)) { return this.delegate.getMongoDatabase(gridFsDatabase); } return this.delegate.getMongoDatabase(); } + private String getGridFsDatabase(MongoConnectionDetails connectionDetails) { + return (connectionDetails.getGridFs() != null) ? connectionDetails.getGridFs().getDatabase() : null; + } + @Override public Mono getMongoDatabase(String dbName) throws DataAccessException { return this.delegate.getMongoDatabase(dbName); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java index fbd2bf2c8f..8d3ce82282 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java @@ -62,8 +62,12 @@ public class MongoAutoConfiguration { } @Bean - MongoPropertiesClientSettingsBuilderCustomizer mongoPropertiesCustomizer(MongoProperties properties) { - return new MongoPropertiesClientSettingsBuilderCustomizer(properties); + StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties, + ObjectProvider connectionDetailsProvider) { + MongoConnectionDetails connectionDetails = connectionDetailsProvider + .getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties)); + return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails.getConnectionString(), + properties.getUuidRepresentation()); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoConnectionDetails.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoConnectionDetails.java new file mode 100644 index 0000000000..bfd107505a --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoConnectionDetails.java @@ -0,0 +1,88 @@ +/* + * Copyright 2012-2023 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 + * + * https://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.boot.autoconfigure.mongo; + +import com.mongodb.ConnectionString; + +import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; + +/** + * Details required to establish a connection to a MongoDB service. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @since 3.1.0 + */ +public interface MongoConnectionDetails extends ConnectionDetails { + + /** + * The {@link ConnectionString} for MongoDB. + * @return the connection string + */ + ConnectionString getConnectionString(); + + /** + * GridFS configuration. + * @return the GridFS configuration or {@code null} + */ + default GridFs getGridFs() { + return null; + } + + /** + * GridFS configuration. + */ + interface GridFs { + + /** + * GridFS database name. + * @return the GridFS database name or {@code null} + */ + String getDatabase(); + + /** + * GridFS bucket name. + * @return the GridFS bucket name or {@code null} + */ + String getBucket(); + + /** + * Factory method to create a new {@link GridFs} instance. + * @param database the database + * @param bucket the bucket name + * @return a new {@link GridFs} instance + */ + static GridFs of(String database, String bucket) { + return new GridFs() { + + @Override + public String getDatabase() { + return database; + } + + @Override + public String getBucket() { + return bucket; + } + + }; + } + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesClientSettingsBuilderCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesClientSettingsBuilderCustomizer.java index df645ae837..222841879b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesClientSettingsBuilderCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesClientSettingsBuilderCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 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. @@ -34,7 +34,10 @@ import org.springframework.util.CollectionUtils; * @author Scott Frederick * @author Safeer Ansari * @since 2.4.0 + * @deprecated since 3.1.0 in favor of + * {@link StandardMongoClientSettingsBuilderCustomizer} */ +@Deprecated(since = "3.1.0", forRemoval = true) public class MongoPropertiesClientSettingsBuilderCustomizer implements MongoClientSettingsBuilderCustomizer, Ordered { private final MongoProperties properties; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.java index 31319fafee..9d877159b1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.java @@ -69,8 +69,12 @@ public class MongoReactiveAutoConfiguration { } @Bean - MongoPropertiesClientSettingsBuilderCustomizer mongoPropertiesCustomizer(MongoProperties properties) { - return new MongoPropertiesClientSettingsBuilderCustomizer(properties); + StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties, + ObjectProvider connectionDetailsProvider) { + MongoConnectionDetails connectionDetails = connectionDetailsProvider + .getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties)); + return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails.getConnectionString(), + properties.getUuidRepresentation()); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/PropertiesMongoConnectionDetails.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/PropertiesMongoConnectionDetails.java new file mode 100644 index 0000000000..f627bf04d0 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/PropertiesMongoConnectionDetails.java @@ -0,0 +1,82 @@ +/* + * Copyright 2012-2023 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 + * + * https://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.boot.autoconfigure.mongo; + +import com.mongodb.ConnectionString; + +/** + * Adapts {@link MongoProperties} to {@link MongoConnectionDetails}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @since 3.1.0 + */ +public class PropertiesMongoConnectionDetails implements MongoConnectionDetails { + + private final MongoProperties properties; + + public PropertiesMongoConnectionDetails(MongoProperties properties) { + this.properties = properties; + } + + @Override + public ConnectionString getConnectionString() { + // mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database.collection][?options]] + if (this.properties.getUri() != null) { + return new ConnectionString(this.properties.getUri()); + } + StringBuilder builder = new StringBuilder("mongodb://"); + if (this.properties.getUsername() != null) { + builder.append(this.properties.getUsername()); + builder.append(":"); + builder.append(this.properties.getPassword()); + builder.append("@"); + } + builder.append((this.properties.getHost() != null) ? this.properties.getHost() : "localhost"); + if (this.properties.getPort() != null) { + builder.append(":"); + builder.append(this.properties.getPort()); + } + if (this.properties.getAdditionalHosts() != null) { + builder.append(String.join(",", this.properties.getAdditionalHosts())); + } + if (this.properties.getMongoClientDatabase() != null || this.properties.getReplicaSetName() != null + || this.properties.getAuthenticationDatabase() != null) { + builder.append("/"); + if (this.properties.getMongoClientDatabase() != null) { + builder.append(this.properties.getMongoClientDatabase()); + } + else if (this.properties.getAuthenticationDatabase() != null) { + builder.append(this.properties.getAuthenticationDatabase()); + } + if (this.properties.getReplicaSetName() != null) { + builder.append("?"); + builder.append("repliceSet="); + builder.append(this.properties.getReplicaSetName()); + } + } + return new ConnectionString(builder.toString()); + } + + @Override + public GridFs getGridFs() { + return GridFs.of(PropertiesMongoConnectionDetails.this.properties.getGridfs().getDatabase(), + PropertiesMongoConnectionDetails.this.properties.getGridfs().getBucket()); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/StandardMongoClientSettingsBuilderCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/StandardMongoClientSettingsBuilderCustomizer.java new file mode 100644 index 0000000000..3876cc3a36 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/StandardMongoClientSettingsBuilderCustomizer.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-2023 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 + * + * https://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.boot.autoconfigure.mongo; + +import com.mongodb.ConnectionString; +import com.mongodb.MongoClientSettings; +import org.bson.UuidRepresentation; + +import org.springframework.core.Ordered; + +/** + * A {@link MongoClientSettingsBuilderCustomizer} that applies standard settings to a + * {@link MongoClientSettings}. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb + * @since 3.1.0 + */ +public class StandardMongoClientSettingsBuilderCustomizer implements MongoClientSettingsBuilderCustomizer, Ordered { + + private final ConnectionString connectionString; + + private final UuidRepresentation uuidRepresentation; + + private int order = 0; + + public StandardMongoClientSettingsBuilderCustomizer(ConnectionString connectionString, + UuidRepresentation uuidRepresentation) { + this.connectionString = connectionString; + this.uuidRepresentation = uuidRepresentation; + } + + @Override + public void customize(MongoClientSettings.Builder settingsBuilder) { + settingsBuilder.uuidRepresentation(this.uuidRepresentation); + settingsBuilder.applyConnectionString(this.connectionString); + } + + @Override + public int getOrder() { + return this.order; + } + + /** + * Set the order value of this object. + * @param order the new order value + * @see #getOrder() + */ + public void setOrder(int order) { + this.order = order; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java index 4f0b12e0b1..6f75319a6e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java @@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.data.mongo; import java.time.LocalDateTime; import java.util.Arrays; +import com.mongodb.ConnectionString; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import org.junit.jupiter.api.Test; @@ -31,6 +32,7 @@ import org.springframework.boot.autoconfigure.data.mongo.city.City; import org.springframework.boot.autoconfigure.data.mongo.country.Country; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -58,6 +60,9 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Josh Long * @author Oliver Gierke * @author Mark Paluch + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb */ class MongoDataAutoConfigurationTests { @@ -80,6 +85,17 @@ class MongoDataAutoConfigurationTests { }); } + @Test + void usesMongoConnectionDetailsIfAvailable() { + this.contextRunner.withUserConfiguration(ConnectionDetailsConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(GridFsTemplate.class); + GridFsTemplate template = context.getBean(GridFsTemplate.class); + assertThat(template).hasFieldOrPropertyWithValue("bucket", "connection-details-bucket"); + MongoDatabaseFactory factory = (MongoDatabaseFactory) ReflectionTestUtils.getField(template, "dbFactory"); + assertThat(factory.getMongoDatabase().getName()).isEqualTo("grid-database-1"); + }); + } + @Test void whenGridFsBucketIsConfiguredThenGridFsTemplateIsAutoConfiguredAndUsesIt() { this.contextRunner.withPropertyValues("spring.data.mongodb.gridfs.bucket:test-bucket").run((context) -> { @@ -250,6 +266,28 @@ class MongoDataAutoConfigurationTests { } + @Configuration(proxyBeanMethods = false) + static class ConnectionDetailsConfiguration { + + @Bean + MongoConnectionDetails mongoConnectionDetails() { + return new MongoConnectionDetails() { + + @Override + public ConnectionString getConnectionString() { + return new ConnectionString("mongodb://localhost/db"); + } + + @Override + public GridFs getGridFs() { + return GridFs.of("grid-database-1", "connection-details-bucket"); + } + + }; + } + + } + static class MyConverter implements Converter { @Override diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfigurationTests.java index 993aa22ac0..ee11af22c9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfigurationTests.java @@ -16,13 +16,17 @@ package org.springframework.boot.autoconfigure.data.mongo; +import com.mongodb.ConnectionString; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails; import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.data.mongodb.gridfs.ReactiveGridFsTemplate; @@ -35,6 +39,9 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Mark Paluch * @author Artsiom Yudovin + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Phillip Webb */ class MongoReactiveDataAutoConfigurationTests { @@ -58,6 +65,15 @@ class MongoReactiveDataAutoConfigurationTests { .run((context) -> assertThat(grisFsTemplateDatabaseName(context)).isEqualTo("grid")); } + @Test + void usesMongoConnectionDetailsIfAvailable() { + this.contextRunner.withUserConfiguration(ConnectionDetailsConfiguration.class).run((context) -> { + assertThat(grisFsTemplateDatabaseName(context)).isEqualTo("grid-database-1"); + ReactiveGridFsTemplate template = context.getBean(ReactiveGridFsTemplate.class); + assertThat(template).hasFieldOrPropertyWithValue("bucket", "connection-details-bucket"); + }); + } + @Test void whenGridFsBucketIsConfiguredThenGridFsTemplateUsesIt() { this.contextRunner.withPropertyValues("spring.data.mongodb.gridfs.bucket:test-bucket").run((context) -> { @@ -82,4 +98,38 @@ class MongoReactiveDataAutoConfigurationTests { return factory.getMongoDatabase().block().getName(); } + @Configuration(proxyBeanMethods = false) + static class ConnectionDetailsConfiguration { + + @Bean + MongoConnectionDetails mongoConnectionDetails() { + return new MongoConnectionDetails() { + + @Override + public ConnectionString getConnectionString() { + return new ConnectionString("mongodb://localhost/db"); + } + + @Override + public GridFs getGridFs() { + return new GridFs() { + + @Override + public String getDatabase() { + return "grid-database-1"; + } + + @Override + public String getBucket() { + return "connection-details-bucket"; + } + + }; + } + + }; + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupportTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupportTests.java index 984360a68e..87861cf2d0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupportTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupportTests.java @@ -43,6 +43,7 @@ import static org.mockito.Mockito.mock; * @author Mark Paluch * @author Artsiom Yudovin * @author Scott Frederick + * @author Mortiz Halbritter */ abstract class MongoClientFactorySupportTests { @@ -110,10 +111,6 @@ abstract class MongoClientFactorySupportTests { assertThat(properties.isAutoIndexCreation()).isTrue(); } - protected T createMongoClient() { - return createMongoClient(null, MongoClientSettings.builder().build()); - } - protected T createMongoClient(MongoClientSettings settings) { return createMongoClient(null, settings); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesClientSettingsBuilderCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesClientSettingsBuilderCustomizerTests.java index 9e7199ae1e..021d298523 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesClientSettingsBuilderCustomizerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesClientSettingsBuilderCustomizerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 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. @@ -32,6 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Scott Frederick */ +@Deprecated(since = "3.1.0", forRemoval = true) class MongoPropertiesClientSettingsBuilderCustomizerTests { private final MongoProperties properties = new MongoProperties(); @@ -188,6 +189,7 @@ class MongoPropertiesClientSettingsBuilderCustomizerTests { assertThat(settings.getRetryWrites()).isFalse(); } + @SuppressWarnings("removal") private MongoClientSettings customizeSettings() { MongoClientSettings.Builder settings = MongoClientSettings.builder(); new MongoPropertiesClientSettingsBuilderCustomizer(this.properties).customize(settings);