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 <mkammerer@vmware.com>
Co-Authored-By: Phillip Webb <pwebb@vmware.com>
pull/34759/head
Andy Wilkinson 2 years ago
parent 042f0c8520
commit 2ef33dc81f

@ -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<MongoConnectionDetails> connectionDetails) {
return new SimpleMongoClientDatabaseFactory(mongoClient,
connectionDetails.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties))
.getConnectionString()
.getDatabase());
}
}

@ -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<MongoConnectionDetails> 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;
}
}
}

@ -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;
* <p>
* Registers a {@link ReactiveMongoTemplate} bean if no other bean of the same type is
* configured.
* <p>
* 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<MongoConnectionDetails> 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<MongoDatabase> 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<MongoDatabase> getMongoDatabase(String dbName) throws DataAccessException {
return this.delegate.getMongoDatabase(dbName);

@ -62,8 +62,12 @@ public class MongoAutoConfiguration {
}
@Bean
MongoPropertiesClientSettingsBuilderCustomizer mongoPropertiesCustomizer(MongoProperties properties) {
return new MongoPropertiesClientSettingsBuilderCustomizer(properties);
StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties,
ObjectProvider<MongoConnectionDetails> connectionDetailsProvider) {
MongoConnectionDetails connectionDetails = connectionDetailsProvider
.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties));
return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails.getConnectionString(),
properties.getUuidRepresentation());
}
}

@ -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;
}
};
}
}
}

@ -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;

@ -69,8 +69,12 @@ public class MongoReactiveAutoConfiguration {
}
@Bean
MongoPropertiesClientSettingsBuilderCustomizer mongoPropertiesCustomizer(MongoProperties properties) {
return new MongoPropertiesClientSettingsBuilderCustomizer(properties);
StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties,
ObjectProvider<MongoConnectionDetails> connectionDetailsProvider) {
MongoConnectionDetails connectionDetails = connectionDetailsProvider
.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties));
return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails.getConnectionString(),
properties.getUuidRepresentation());
}
}

@ -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());
}
}

@ -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;
}
}

@ -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<MongoClient, Boolean> {
@Override

@ -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";
}
};
}
};
}
}
}

@ -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<T> {
@ -110,10 +111,6 @@ abstract class MongoClientFactorySupportTests<T> {
assertThat(properties.isAutoIndexCreation()).isTrue();
}
protected T createMongoClient() {
return createMongoClient(null, MongoClientSettings.builder().build());
}
protected T createMongoClient(MongoClientSettings settings) {
return createMongoClient(null, settings);
}

@ -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);

Loading…
Cancel
Save