Allow Mongo database property to override database in URI

This commit restores the previous behavior of MongoDB auto-
configuration, where the value of the `spring.data.mongodb.database`
property takes precedence over the database specified in a
`spring.data.mongodb.uri` property.

Fixes gh-35566
This commit is contained in:
Scott Frederick
2023-05-25 17:29:45 -05:00
parent 715204dde9
commit 593fa1dc42
4 changed files with 133 additions and 4 deletions

View File

@@ -35,6 +35,7 @@ import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
* @author Stephane Nicoll
* @author Moritz Halbritter
* @author Phillip Webb
* @author Scott Frederick
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(MongoDatabaseFactory.class)
@@ -44,7 +45,11 @@ class MongoDatabaseFactoryConfiguration {
@Bean
MongoDatabaseFactorySupport<?> mongoDatabaseFactory(MongoClient mongoClient, MongoProperties properties,
MongoConnectionDetails connectionDetails) {
return new SimpleMongoClientDatabaseFactory(mongoClient, connectionDetails.getConnectionString().getDatabase());
String database = properties.getDatabase();
if (database == null) {
database = connectionDetails.getConnectionString().getDatabase();
}
return new SimpleMongoClientDatabaseFactory(mongoClient, database);
}
}

View File

@@ -67,6 +67,7 @@ import org.springframework.util.StringUtils;
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
* @since 2.0.0
*/
@AutoConfiguration(after = MongoReactiveAutoConfiguration.class)
@@ -84,9 +85,13 @@ public class MongoReactiveDataAutoConfiguration {
@Bean
@ConditionalOnMissingBean(ReactiveMongoDatabaseFactory.class)
public SimpleReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory(MongoClient mongo) {
return new SimpleReactiveMongoDatabaseFactory(mongo,
this.connectionDetails.getConnectionString().getDatabase());
public SimpleReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory(MongoClient mongo,
MongoProperties properties) {
String database = properties.getDatabase();
if (database == null) {
database = this.connectionDetails.getConnectionString().getDatabase();
}
return new SimpleReactiveMongoDatabaseFactory(mongo, database);
}
@Bean

View File

@@ -64,6 +64,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
*/
class MongoDataAutoConfigurationTests {
@@ -226,6 +227,64 @@ class MongoDataAutoConfigurationTests {
.run((context) -> assertThat(context).hasSingleBean(MongoTemplate.class));
}
@Test
void databaseHasDefault() {
this.contextRunner.run((context) -> {
MongoDatabaseFactory factory = context.getBean(MongoDatabaseFactory.class);
assertThat(factory).isInstanceOf(SimpleMongoClientDatabaseFactory.class);
assertThat(factory.getMongoDatabase().getName()).isEqualTo("test");
});
}
@Test
void databasePropertyIsUsed() {
this.contextRunner.withPropertyValues("spring.data.mongodb.database=mydb").run((context) -> {
MongoDatabaseFactory factory = context.getBean(MongoDatabaseFactory.class);
assertThat(factory).isInstanceOf(SimpleMongoClientDatabaseFactory.class);
assertThat(factory.getMongoDatabase().getName()).isEqualTo("mydb");
});
}
@Test
void databaseInUriPropertyIsUsed() {
this.contextRunner.withPropertyValues("spring.data.mongodb.uri=mongodb://mongo.example.com/mydb")
.run((context) -> {
MongoDatabaseFactory factory = context.getBean(MongoDatabaseFactory.class);
assertThat(factory).isInstanceOf(SimpleMongoClientDatabaseFactory.class);
assertThat(factory.getMongoDatabase().getName()).isEqualTo("mydb");
});
}
@Test
void databasePropertyOverridesUriProperty() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.uri=mongodb://mongo.example.com/notused",
"spring.data.mongodb.database=mydb")
.run((context) -> {
MongoDatabaseFactory factory = context.getBean(MongoDatabaseFactory.class);
assertThat(factory).isInstanceOf(SimpleMongoClientDatabaseFactory.class);
assertThat(factory.getMongoDatabase().getName()).isEqualTo("mydb");
});
}
@Test
void databasePropertyIsUsedWhenNoDatabaseInUri() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.uri=mongodb://mongo.example.com/",
"spring.data.mongodb.database=mydb")
.run((context) -> {
MongoDatabaseFactory factory = context.getBean(MongoDatabaseFactory.class);
assertThat(factory).isInstanceOf(SimpleMongoClientDatabaseFactory.class);
assertThat(factory.getMongoDatabase().getName()).isEqualTo("mydb");
});
}
@Test
void contextFailsWhenDatabaseNotSet() {
this.contextRunner.withPropertyValues("spring.data.mongodb.uri=mongodb://mongo.example.com/")
.run((context) -> assertThat(context).getFailure().hasMessageContaining("Database name must not be empty"));
}
@Test
void definesPropertiesBasedConnectionDetailsByDefault() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesMongoConnectionDetails.class));

View File

@@ -29,6 +29,7 @@ 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.core.SimpleReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.gridfs.ReactiveGridFsTemplate;
import org.springframework.test.util.ReflectionTestUtils;
@@ -42,6 +43,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
*/
class MongoReactiveDataAutoConfigurationTests {
@@ -90,6 +92,64 @@ class MongoReactiveDataAutoConfigurationTests {
runner.run((context) -> assertThat(context).doesNotHaveBean(MongoReactiveDataAutoConfiguration.class));
}
@Test
void databaseHasDefault() {
this.contextRunner.run((context) -> {
ReactiveMongoDatabaseFactory factory = context.getBean(ReactiveMongoDatabaseFactory.class);
assertThat(factory).isInstanceOf(SimpleReactiveMongoDatabaseFactory.class);
assertThat(factory.getMongoDatabase().block().getName()).isEqualTo("test");
});
}
@Test
void databasePropertyIsUsed() {
this.contextRunner.withPropertyValues("spring.data.mongodb.database=mydb").run((context) -> {
ReactiveMongoDatabaseFactory factory = context.getBean(ReactiveMongoDatabaseFactory.class);
assertThat(factory).isInstanceOf(SimpleReactiveMongoDatabaseFactory.class);
assertThat(factory.getMongoDatabase().block().getName()).isEqualTo("mydb");
});
}
@Test
void databaseInUriPropertyIsUsed() {
this.contextRunner.withPropertyValues("spring.data.mongodb.uri=mongodb://mongo.example.com/mydb")
.run((context) -> {
ReactiveMongoDatabaseFactory factory = context.getBean(ReactiveMongoDatabaseFactory.class);
assertThat(factory).isInstanceOf(SimpleReactiveMongoDatabaseFactory.class);
assertThat(factory.getMongoDatabase().block().getName()).isEqualTo("mydb");
});
}
@Test
void databasePropertyOverridesUriProperty() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.uri=mongodb://mongo.example.com/notused",
"spring.data.mongodb.database=mydb")
.run((context) -> {
ReactiveMongoDatabaseFactory factory = context.getBean(ReactiveMongoDatabaseFactory.class);
assertThat(factory).isInstanceOf(SimpleReactiveMongoDatabaseFactory.class);
assertThat(factory.getMongoDatabase().block().getName()).isEqualTo("mydb");
});
}
@Test
void databasePropertyIsUsedWhenNoDatabaseInUri() {
this.contextRunner
.withPropertyValues("spring.data.mongodb.uri=mongodb://mongo.example.com/",
"spring.data.mongodb.database=mydb")
.run((context) -> {
ReactiveMongoDatabaseFactory factory = context.getBean(ReactiveMongoDatabaseFactory.class);
assertThat(factory).isInstanceOf(SimpleReactiveMongoDatabaseFactory.class);
assertThat(factory.getMongoDatabase().block().getName()).isEqualTo("mydb");
});
}
@Test
void contextFailsWhenDatabaseNotSet() {
this.contextRunner.withPropertyValues("spring.data.mongodb.uri=mongodb://mongo.example.com/")
.run((context) -> assertThat(context).getFailure().hasMessageContaining("Database name must not be empty"));
}
private String grisFsTemplateDatabaseName(AssertableApplicationContext context) {
assertThat(context).hasSingleBean(ReactiveGridFsTemplate.class);
ReactiveGridFsTemplate template = context.getBean(ReactiveGridFsTemplate.class);