mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Always define connection details beans
Closes gh-34776
This commit is contained in:
parent
466b81f13d
commit
d4980ea993
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -50,6 +50,12 @@ import org.springframework.context.annotation.Import;
|
|||||||
@ConditionalOnEnabledTracing
|
@ConditionalOnEnabledTracing
|
||||||
public class ZipkinAutoConfiguration {
|
public class ZipkinAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(ZipkinConnectionDetails.class)
|
||||||
|
PropertiesZipkinConnectionDetails zipkinConnectionDetails(ZipkinProperties properties) {
|
||||||
|
return new PropertiesZipkinConnectionDetails(properties);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public BytesEncoder<Span> spanBytesEncoder() {
|
public BytesEncoder<Span> spanBytesEncoder() {
|
||||||
|
@ -64,6 +64,25 @@ class ZipkinAutoConfigurationTests {
|
|||||||
.run((context) -> assertThat(context).doesNotHaveBean(BytesEncoder.class));
|
.run((context) -> assertThat(context).doesNotHaveBean(BytesEncoder.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesZipkinConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldUseCustomConnectionDetailsWhenDefined() {
|
||||||
|
this.contextRunner.withBean(ZipkinConnectionDetails.class, () -> new ZipkinConnectionDetails() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSpanEndpoint() {
|
||||||
|
return "http://localhost";
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(ZipkinConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesZipkinConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
private static class CustomConfiguration {
|
private static class CustomConfiguration {
|
||||||
|
|
||||||
|
@ -25,13 +25,12 @@ import java.util.List;
|
|||||||
* @author Moritz Halbritter
|
* @author Moritz Halbritter
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @since 3.1.0
|
|
||||||
*/
|
*/
|
||||||
public class PropertiesRabbitConnectionDetails implements RabbitConnectionDetails {
|
class PropertiesRabbitConnectionDetails implements RabbitConnectionDetails {
|
||||||
|
|
||||||
private final RabbitProperties properties;
|
private final RabbitProperties properties;
|
||||||
|
|
||||||
public PropertiesRabbitConnectionDetails(RabbitProperties properties) {
|
PropertiesRabbitConnectionDetails(RabbitProperties properties) {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,22 +82,24 @@ public class RabbitAutoConfiguration {
|
|||||||
|
|
||||||
private final RabbitProperties properties;
|
private final RabbitProperties properties;
|
||||||
|
|
||||||
private final RabbitConnectionDetails connectionDetails;
|
|
||||||
|
|
||||||
protected RabbitConnectionFactoryCreator(RabbitProperties properties,
|
protected RabbitConnectionFactoryCreator(RabbitProperties properties,
|
||||||
ObjectProvider<RabbitConnectionDetails> connectionDetails) {
|
ObjectProvider<RabbitConnectionDetails> connectionDetails) {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.connectionDetails = connectionDetails
|
}
|
||||||
.getIfAvailable(() -> new PropertiesRabbitConnectionDetails(properties));
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(RabbitConnectionDetails.class)
|
||||||
|
RabbitConnectionDetails rabbitConnectionDetails() {
|
||||||
|
return new PropertiesRabbitConnectionDetails(this.properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
RabbitConnectionFactoryBeanConfigurer rabbitConnectionFactoryBeanConfigurer(ResourceLoader resourceLoader,
|
RabbitConnectionFactoryBeanConfigurer rabbitConnectionFactoryBeanConfigurer(ResourceLoader resourceLoader,
|
||||||
ObjectProvider<CredentialsProvider> credentialsProvider,
|
RabbitConnectionDetails connectionDetails, ObjectProvider<CredentialsProvider> credentialsProvider,
|
||||||
ObjectProvider<CredentialsRefreshService> credentialsRefreshService) {
|
ObjectProvider<CredentialsRefreshService> credentialsRefreshService) {
|
||||||
RabbitConnectionFactoryBeanConfigurer configurer = new RabbitConnectionFactoryBeanConfigurer(resourceLoader,
|
RabbitConnectionFactoryBeanConfigurer configurer = new RabbitConnectionFactoryBeanConfigurer(resourceLoader,
|
||||||
this.properties, this.connectionDetails);
|
this.properties, connectionDetails);
|
||||||
configurer.setCredentialsProvider(credentialsProvider.getIfUnique());
|
configurer.setCredentialsProvider(credentialsProvider.getIfUnique());
|
||||||
configurer.setCredentialsRefreshService(credentialsRefreshService.getIfUnique());
|
configurer.setCredentialsRefreshService(credentialsRefreshService.getIfUnique());
|
||||||
return configurer;
|
return configurer;
|
||||||
@ -105,10 +107,10 @@ public class RabbitAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
CachingConnectionFactoryConfigurer rabbitConnectionFactoryConfigurer(
|
CachingConnectionFactoryConfigurer rabbitConnectionFactoryConfigurer(RabbitConnectionDetails connectionDetails,
|
||||||
ObjectProvider<ConnectionNameStrategy> connectionNameStrategy) {
|
ObjectProvider<ConnectionNameStrategy> connectionNameStrategy) {
|
||||||
CachingConnectionFactoryConfigurer configurer = new CachingConnectionFactoryConfigurer(this.properties,
|
CachingConnectionFactoryConfigurer configurer = new CachingConnectionFactoryConfigurer(this.properties,
|
||||||
this.connectionDetails);
|
connectionDetails);
|
||||||
configurer.setConnectionNameStrategy(connectionNameStrategy.getIfUnique());
|
configurer.setConnectionNameStrategy(connectionNameStrategy.getIfUnique());
|
||||||
return configurer;
|
return configurer;
|
||||||
}
|
}
|
||||||
|
@ -84,13 +84,14 @@ public class CassandraAutoConfiguration {
|
|||||||
|
|
||||||
private final CassandraProperties properties;
|
private final CassandraProperties properties;
|
||||||
|
|
||||||
private final CassandraConnectionDetails connectionDetails;
|
CassandraAutoConfiguration(CassandraProperties properties) {
|
||||||
|
|
||||||
CassandraAutoConfiguration(CassandraProperties properties,
|
|
||||||
ObjectProvider<CassandraConnectionDetails> connectionDetails) {
|
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.connectionDetails = connectionDetails
|
}
|
||||||
.getIfAvailable(() -> new PropertiesCassandraConnectionDetails(properties));
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(CassandraConnectionDetails.class)
|
||||||
|
PropertiesCassandraConnectionDetails cassandraConnectionDetails() {
|
||||||
|
return new PropertiesCassandraConnectionDetails(this.properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ -104,24 +105,25 @@ public class CassandraAutoConfiguration {
|
|||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
@Scope("prototype")
|
@Scope("prototype")
|
||||||
public CqlSessionBuilder cassandraSessionBuilder(DriverConfigLoader driverConfigLoader,
|
public CqlSessionBuilder cassandraSessionBuilder(DriverConfigLoader driverConfigLoader,
|
||||||
|
CassandraConnectionDetails connectionDetails,
|
||||||
ObjectProvider<CqlSessionBuilderCustomizer> builderCustomizers) {
|
ObjectProvider<CqlSessionBuilderCustomizer> builderCustomizers) {
|
||||||
CqlSessionBuilder builder = CqlSession.builder().withConfigLoader(driverConfigLoader);
|
CqlSessionBuilder builder = CqlSession.builder().withConfigLoader(driverConfigLoader);
|
||||||
configureAuthentication(builder);
|
configureAuthentication(builder, connectionDetails);
|
||||||
configureSsl(builder);
|
configureSsl(builder, connectionDetails);
|
||||||
builder.withKeyspace(this.properties.getKeyspaceName());
|
builder.withKeyspace(this.properties.getKeyspaceName());
|
||||||
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
|
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureAuthentication(CqlSessionBuilder builder) {
|
private void configureAuthentication(CqlSessionBuilder builder, CassandraConnectionDetails connectionDetails) {
|
||||||
String username = this.connectionDetails.getUsername();
|
String username = connectionDetails.getUsername();
|
||||||
if (username != null) {
|
if (username != null) {
|
||||||
builder.withAuthCredentials(username, this.connectionDetails.getPassword());
|
builder.withAuthCredentials(username, connectionDetails.getPassword());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureSsl(CqlSessionBuilder builder) {
|
private void configureSsl(CqlSessionBuilder builder, CassandraConnectionDetails connectionDetails) {
|
||||||
if (this.connectionDetails instanceof PropertiesCassandraConnectionDetails && this.properties.isSsl()) {
|
if (connectionDetails instanceof PropertiesCassandraConnectionDetails && this.properties.isSsl()) {
|
||||||
try {
|
try {
|
||||||
builder.withSslContext(SSLContext.getDefault());
|
builder.withSslContext(SSLContext.getDefault());
|
||||||
}
|
}
|
||||||
@ -133,18 +135,18 @@ public class CassandraAutoConfiguration {
|
|||||||
|
|
||||||
@Bean(destroyMethod = "")
|
@Bean(destroyMethod = "")
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public DriverConfigLoader cassandraDriverConfigLoader(
|
public DriverConfigLoader cassandraDriverConfigLoader(CassandraConnectionDetails connectionDetails,
|
||||||
ObjectProvider<DriverConfigLoaderBuilderCustomizer> builderCustomizers) {
|
ObjectProvider<DriverConfigLoaderBuilderCustomizer> builderCustomizers) {
|
||||||
ProgrammaticDriverConfigLoaderBuilder builder = new DefaultProgrammaticDriverConfigLoaderBuilder(
|
ProgrammaticDriverConfigLoaderBuilder builder = new DefaultProgrammaticDriverConfigLoaderBuilder(
|
||||||
() -> cassandraConfiguration(), DefaultDriverConfigLoader.DEFAULT_ROOT_PATH);
|
() -> cassandraConfiguration(connectionDetails), DefaultDriverConfigLoader.DEFAULT_ROOT_PATH);
|
||||||
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
|
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Config cassandraConfiguration() {
|
private Config cassandraConfiguration(CassandraConnectionDetails connectionDetails) {
|
||||||
ConfigFactory.invalidateCaches();
|
ConfigFactory.invalidateCaches();
|
||||||
Config config = ConfigFactory.defaultOverrides();
|
Config config = ConfigFactory.defaultOverrides();
|
||||||
config = config.withFallback(mapConfig());
|
config = config.withFallback(mapConfig(connectionDetails));
|
||||||
if (this.properties.getConfig() != null) {
|
if (this.properties.getConfig() != null) {
|
||||||
config = config.withFallback(loadConfig(this.properties.getConfig()));
|
config = config.withFallback(loadConfig(this.properties.getConfig()));
|
||||||
}
|
}
|
||||||
@ -162,24 +164,24 @@ public class CassandraAutoConfiguration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Config mapConfig() {
|
private Config mapConfig(CassandraConnectionDetails connectionDetails) {
|
||||||
CassandraDriverOptions options = new CassandraDriverOptions();
|
CassandraDriverOptions options = new CassandraDriverOptions();
|
||||||
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||||
map.from(this.properties.getSessionName())
|
map.from(this.properties.getSessionName())
|
||||||
.whenHasText()
|
.whenHasText()
|
||||||
.to((sessionName) -> options.add(DefaultDriverOption.SESSION_NAME, sessionName));
|
.to((sessionName) -> options.add(DefaultDriverOption.SESSION_NAME, sessionName));
|
||||||
map.from(this.connectionDetails.getUsername())
|
map.from(connectionDetails.getUsername())
|
||||||
.to((value) -> options.add(DefaultDriverOption.AUTH_PROVIDER_USER_NAME, value)
|
.to((value) -> options.add(DefaultDriverOption.AUTH_PROVIDER_USER_NAME, value)
|
||||||
.add(DefaultDriverOption.AUTH_PROVIDER_PASSWORD, this.connectionDetails.getPassword()));
|
.add(DefaultDriverOption.AUTH_PROVIDER_PASSWORD, connectionDetails.getPassword()));
|
||||||
map.from(this.properties::getCompression)
|
map.from(this.properties::getCompression)
|
||||||
.to((compression) -> options.add(DefaultDriverOption.PROTOCOL_COMPRESSION, compression));
|
.to((compression) -> options.add(DefaultDriverOption.PROTOCOL_COMPRESSION, compression));
|
||||||
mapConnectionOptions(options);
|
mapConnectionOptions(options);
|
||||||
mapPoolingOptions(options);
|
mapPoolingOptions(options);
|
||||||
mapRequestOptions(options);
|
mapRequestOptions(options);
|
||||||
mapControlConnectionOptions(options);
|
mapControlConnectionOptions(options);
|
||||||
map.from(mapContactPoints())
|
map.from(mapContactPoints(connectionDetails))
|
||||||
.to((contactPoints) -> options.add(DefaultDriverOption.CONTACT_POINTS, contactPoints));
|
.to((contactPoints) -> options.add(DefaultDriverOption.CONTACT_POINTS, contactPoints));
|
||||||
map.from(this.connectionDetails.getLocalDatacenter())
|
map.from(connectionDetails.getLocalDatacenter())
|
||||||
.whenHasText()
|
.whenHasText()
|
||||||
.to((localDatacenter) -> options.add(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, localDatacenter));
|
.to((localDatacenter) -> options.add(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, localDatacenter));
|
||||||
return options.build();
|
return options.build();
|
||||||
@ -244,11 +246,8 @@ public class CassandraAutoConfiguration {
|
|||||||
.to((timeout) -> options.add(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, timeout));
|
.to((timeout) -> options.add(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, timeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> mapContactPoints() {
|
private List<String> mapContactPoints(CassandraConnectionDetails connectionDetails) {
|
||||||
return this.connectionDetails.getContactPoints()
|
return connectionDetails.getContactPoints().stream().map((node) -> node.host() + ":" + node.port()).toList();
|
||||||
.stream()
|
|
||||||
.map((node) -> node.host() + ":" + node.port())
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CassandraDriverOptions {
|
private static class CassandraDriverOptions {
|
||||||
@ -289,7 +288,7 @@ public class CassandraAutoConfiguration {
|
|||||||
/**
|
/**
|
||||||
* Adapts {@link CassandraProperties} to {@link CassandraConnectionDetails}.
|
* Adapts {@link CassandraProperties} to {@link CassandraConnectionDetails}.
|
||||||
*/
|
*/
|
||||||
private static final class PropertiesCassandraConnectionDetails implements CassandraConnectionDetails {
|
static final class PropertiesCassandraConnectionDetails implements CassandraConnectionDetails {
|
||||||
|
|
||||||
private final CassandraProperties properties;
|
private final CassandraProperties properties;
|
||||||
|
|
||||||
|
@ -69,34 +69,37 @@ public class CouchbaseAutoConfiguration {
|
|||||||
|
|
||||||
private final CouchbaseProperties properties;
|
private final CouchbaseProperties properties;
|
||||||
|
|
||||||
private final CouchbaseConnectionDetails connectionDetails;
|
|
||||||
|
|
||||||
CouchbaseAutoConfiguration(CouchbaseProperties properties,
|
CouchbaseAutoConfiguration(CouchbaseProperties properties,
|
||||||
ObjectProvider<CouchbaseConnectionDetails> connectionDetails) {
|
ObjectProvider<CouchbaseConnectionDetails> connectionDetails) {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.connectionDetails = connectionDetails
|
}
|
||||||
.getIfAvailable(() -> new PropertiesCouchbaseConnectionDetails(properties));
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(CouchbaseConnectionDetails.class)
|
||||||
|
PropertiesCouchbaseConnectionDetails couchbaseConnectionDetails() {
|
||||||
|
return new PropertiesCouchbaseConnectionDetails(this.properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public ClusterEnvironment couchbaseClusterEnvironment(
|
public ClusterEnvironment couchbaseClusterEnvironment(CouchbaseConnectionDetails connectionDetails,
|
||||||
ObjectProvider<ClusterEnvironmentBuilderCustomizer> customizers) {
|
ObjectProvider<ClusterEnvironmentBuilderCustomizer> customizers) {
|
||||||
Builder builder = initializeEnvironmentBuilder();
|
Builder builder = initializeEnvironmentBuilder(connectionDetails);
|
||||||
customizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
|
customizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(destroyMethod = "disconnect")
|
@Bean(destroyMethod = "disconnect")
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public Cluster couchbaseCluster(ClusterEnvironment couchbaseClusterEnvironment) {
|
public Cluster couchbaseCluster(ClusterEnvironment couchbaseClusterEnvironment,
|
||||||
|
CouchbaseConnectionDetails connectionDetails) {
|
||||||
ClusterOptions options = ClusterOptions
|
ClusterOptions options = ClusterOptions
|
||||||
.clusterOptions(this.connectionDetails.getUsername(), this.connectionDetails.getPassword())
|
.clusterOptions(connectionDetails.getUsername(), connectionDetails.getPassword())
|
||||||
.environment(couchbaseClusterEnvironment);
|
.environment(couchbaseClusterEnvironment);
|
||||||
return Cluster.connect(this.connectionDetails.getConnectionString(), options);
|
return Cluster.connect(connectionDetails.getConnectionString(), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClusterEnvironment.Builder initializeEnvironmentBuilder() {
|
private ClusterEnvironment.Builder initializeEnvironmentBuilder(CouchbaseConnectionDetails connectionDetails) {
|
||||||
ClusterEnvironment.Builder builder = ClusterEnvironment.builder();
|
ClusterEnvironment.Builder builder = ClusterEnvironment.builder();
|
||||||
Timeouts timeouts = this.properties.getEnv().getTimeouts();
|
Timeouts timeouts = this.properties.getEnv().getTimeouts();
|
||||||
builder.timeoutConfig((config) -> config.kvTimeout(timeouts.getKeyValue())
|
builder.timeoutConfig((config) -> config.kvTimeout(timeouts.getKeyValue())
|
||||||
@ -112,7 +115,7 @@ public class CouchbaseAutoConfiguration {
|
|||||||
builder.ioConfig((config) -> config.maxHttpConnections(io.getMaxEndpoints())
|
builder.ioConfig((config) -> config.maxHttpConnections(io.getMaxEndpoints())
|
||||||
.numKvConnections(io.getMinEndpoints())
|
.numKvConnections(io.getMinEndpoints())
|
||||||
.idleHttpConnectionTimeout(io.getIdleHttpConnectionTimeout()));
|
.idleHttpConnectionTimeout(io.getIdleHttpConnectionTimeout()));
|
||||||
if ((this.connectionDetails instanceof PropertiesCouchbaseConnectionDetails)
|
if ((connectionDetails instanceof PropertiesCouchbaseConnectionDetails)
|
||||||
&& this.properties.getEnv().getSsl().getEnabled()) {
|
&& this.properties.getEnv().getSsl().getEnabled()) {
|
||||||
builder.securityConfig((config) -> config.enableTls(true)
|
builder.securityConfig((config) -> config.enableTls(true)
|
||||||
.trustManagerFactory(getTrustManagerFactory(this.properties.getEnv().getSsl())));
|
.trustManagerFactory(getTrustManagerFactory(this.properties.getEnv().getSsl())));
|
||||||
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -21,9 +21,13 @@ import com.mongodb.client.MongoClient;
|
|||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
||||||
|
import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
|
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
|
||||||
@ -53,4 +57,10 @@ import org.springframework.data.mongodb.gridfs.GridFsTemplate;
|
|||||||
MongoDatabaseFactoryDependentConfiguration.class })
|
MongoDatabaseFactoryDependentConfiguration.class })
|
||||||
public class MongoDataAutoConfiguration {
|
public class MongoDataAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(MongoConnectionDetails.class)
|
||||||
|
PropertiesMongoConnectionDetails mongoConnectionDetails(MongoProperties properties) {
|
||||||
|
return new PropertiesMongoConnectionDetails(properties);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,10 @@ package org.springframework.boot.autoconfigure.data.mongo;
|
|||||||
|
|
||||||
import com.mongodb.client.MongoClient;
|
import com.mongodb.client.MongoClient;
|
||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
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.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.mongodb.MongoDatabaseFactory;
|
import org.springframework.data.mongodb.MongoDatabaseFactory;
|
||||||
@ -45,11 +43,8 @@ class MongoDatabaseFactoryConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
MongoDatabaseFactorySupport<?> mongoDatabaseFactory(MongoClient mongoClient, MongoProperties properties,
|
MongoDatabaseFactorySupport<?> mongoDatabaseFactory(MongoClient mongoClient, MongoProperties properties,
|
||||||
ObjectProvider<MongoConnectionDetails> connectionDetails) {
|
MongoConnectionDetails connectionDetails) {
|
||||||
return new SimpleMongoClientDatabaseFactory(mongoClient,
|
return new SimpleMongoClientDatabaseFactory(mongoClient, connectionDetails.getConnectionString().getDatabase());
|
||||||
connectionDetails.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties))
|
|
||||||
.getConnectionString()
|
|
||||||
.getDatabase());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,12 @@ import com.mongodb.ClientSessionOptions;
|
|||||||
import com.mongodb.client.ClientSession;
|
import com.mongodb.client.ClientSession;
|
||||||
import com.mongodb.client.MongoDatabase;
|
import com.mongodb.client.MongoDatabase;
|
||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails.GridFs;
|
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails.GridFs;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoProperties.Gridfs;
|
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.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
@ -76,9 +74,7 @@ class MongoDatabaseFactoryDependentConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(GridFsOperations.class)
|
@ConditionalOnMissingBean(GridFsOperations.class)
|
||||||
GridFsTemplate gridFsTemplate(MongoProperties properties, MongoDatabaseFactory factory, MongoTemplate mongoTemplate,
|
GridFsTemplate gridFsTemplate(MongoProperties properties, MongoDatabaseFactory factory, MongoTemplate mongoTemplate,
|
||||||
ObjectProvider<MongoConnectionDetails> connectionDetailsProvider) {
|
MongoConnectionDetails connectionDetails) {
|
||||||
MongoConnectionDetails connectionDetails = connectionDetailsProvider
|
|
||||||
.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties));
|
|
||||||
return new GridFsTemplate(new GridFsMongoDatabaseFactory(factory, connectionDetails),
|
return new GridFsTemplate(new GridFsMongoDatabaseFactory(factory, connectionDetails),
|
||||||
mongoTemplate.getConverter(),
|
mongoTemplate.getConverter(),
|
||||||
(connectionDetails.getGridFs() != null) ? connectionDetails.getGridFs().getBucket() : null);
|
(connectionDetails.getGridFs() != null) ? connectionDetails.getGridFs().getBucket() : null);
|
||||||
|
@ -26,7 +26,6 @@ import org.bson.codecs.Codec;
|
|||||||
import org.bson.codecs.configuration.CodecRegistry;
|
import org.bson.codecs.configuration.CodecRegistry;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
@ -36,7 +35,6 @@ import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
|||||||
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails.GridFs;
|
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails.GridFs;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration;
|
import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails;
|
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
@ -80,10 +78,8 @@ public class MongoReactiveDataAutoConfiguration {
|
|||||||
|
|
||||||
private final MongoConnectionDetails connectionDetails;
|
private final MongoConnectionDetails connectionDetails;
|
||||||
|
|
||||||
MongoReactiveDataAutoConfiguration(MongoProperties properties,
|
MongoReactiveDataAutoConfiguration(MongoConnectionDetails connectionDetails) {
|
||||||
ObjectProvider<MongoConnectionDetails> connectionDetails) {
|
this.connectionDetails = connectionDetails;
|
||||||
this.connectionDetails = connectionDetails
|
|
||||||
.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -55,10 +55,9 @@ class JedisConnectionConfiguration extends RedisConnectionConfiguration {
|
|||||||
JedisConnectionConfiguration(RedisProperties properties,
|
JedisConnectionConfiguration(RedisProperties properties,
|
||||||
ObjectProvider<RedisStandaloneConfiguration> standaloneConfigurationProvider,
|
ObjectProvider<RedisStandaloneConfiguration> standaloneConfigurationProvider,
|
||||||
ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
|
ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
|
||||||
ObjectProvider<RedisClusterConfiguration> clusterConfiguration,
|
ObjectProvider<RedisClusterConfiguration> clusterConfiguration, RedisConnectionDetails connectionDetails) {
|
||||||
ObjectProvider<RedisConnectionDetails> connectionDetailsProvider) {
|
super(properties, connectionDetails, standaloneConfigurationProvider, sentinelConfiguration,
|
||||||
super(properties, standaloneConfigurationProvider, sentinelConfiguration, clusterConfiguration,
|
clusterConfiguration);
|
||||||
connectionDetailsProvider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -64,9 +64,9 @@ class LettuceConnectionConfiguration extends RedisConnectionConfiguration {
|
|||||||
ObjectProvider<RedisStandaloneConfiguration> standaloneConfigurationProvider,
|
ObjectProvider<RedisStandaloneConfiguration> standaloneConfigurationProvider,
|
||||||
ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
|
ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
|
||||||
ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider,
|
ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider,
|
||||||
ObjectProvider<RedisConnectionDetails> connectionDetailsProvider) {
|
RedisConnectionDetails connectionDetails) {
|
||||||
super(properties, standaloneConfigurationProvider, sentinelConfigurationProvider, clusterConfigurationProvider,
|
super(properties, connectionDetails, standaloneConfigurationProvider, sentinelConfigurationProvider,
|
||||||
connectionDetailsProvider);
|
clusterConfigurationProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(destroyMethod = "shutdown")
|
@Bean(destroyMethod = "shutdown")
|
||||||
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -49,6 +49,12 @@ import org.springframework.data.redis.core.StringRedisTemplate;
|
|||||||
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
|
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
|
||||||
public class RedisAutoConfiguration {
|
public class RedisAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(RedisConnectionDetails.class)
|
||||||
|
PropertiesRedisConnectionDetails redisConnectionDetails(RedisProperties properties) {
|
||||||
|
return new PropertiesRedisConnectionDetails(properties);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(name = "redisTemplate")
|
@ConditionalOnMissingBean(name = "redisTemplate")
|
||||||
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
|
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
|
||||||
|
@ -60,17 +60,15 @@ abstract class RedisConnectionConfiguration {
|
|||||||
|
|
||||||
private final RedisConnectionDetails connectionDetails;
|
private final RedisConnectionDetails connectionDetails;
|
||||||
|
|
||||||
protected RedisConnectionConfiguration(RedisProperties properties,
|
protected RedisConnectionConfiguration(RedisProperties properties, RedisConnectionDetails connectionDetails,
|
||||||
ObjectProvider<RedisStandaloneConfiguration> standaloneConfigurationProvider,
|
ObjectProvider<RedisStandaloneConfiguration> standaloneConfigurationProvider,
|
||||||
ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
|
ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
|
||||||
ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider,
|
ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider) {
|
||||||
ObjectProvider<RedisConnectionDetails> connectionDetailsProvider) {
|
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.standaloneConfiguration = standaloneConfigurationProvider.getIfAvailable();
|
this.standaloneConfiguration = standaloneConfigurationProvider.getIfAvailable();
|
||||||
this.sentinelConfiguration = sentinelConfigurationProvider.getIfAvailable();
|
this.sentinelConfiguration = sentinelConfigurationProvider.getIfAvailable();
|
||||||
this.clusterConfiguration = clusterConfigurationProvider.getIfAvailable();
|
this.clusterConfiguration = clusterConfigurationProvider.getIfAvailable();
|
||||||
this.connectionDetails = connectionDetailsProvider
|
this.connectionDetails = connectionDetails;
|
||||||
.getIfAvailable(() -> new PropertiesRedisConnectionDetails(properties));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final RedisStandaloneConfiguration getStandaloneConfig() {
|
protected final RedisStandaloneConfiguration getStandaloneConfig() {
|
||||||
|
@ -62,24 +62,27 @@ class ElasticsearchRestClientConfigurations {
|
|||||||
|
|
||||||
private final ElasticsearchProperties properties;
|
private final ElasticsearchProperties properties;
|
||||||
|
|
||||||
private final ElasticsearchConnectionDetails connectionDetails;
|
|
||||||
|
|
||||||
RestClientBuilderConfiguration(ElasticsearchProperties properties,
|
RestClientBuilderConfiguration(ElasticsearchProperties properties,
|
||||||
ObjectProvider<ElasticsearchConnectionDetails> connectionDetails) {
|
ObjectProvider<ElasticsearchConnectionDetails> connectionDetails) {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.connectionDetails = connectionDetails
|
|
||||||
.getIfAvailable(() -> new PropertiesElasticsearchConnectionDetails(properties));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
RestClientBuilderCustomizer defaultRestClientBuilderCustomizer() {
|
@ConditionalOnMissingBean(ElasticsearchConnectionDetails.class)
|
||||||
return new DefaultRestClientBuilderCustomizer(this.properties, this.connectionDetails);
|
PropertiesElasticsearchConnectionDetails elasticsearchConnectionDetails() {
|
||||||
|
return new PropertiesElasticsearchConnectionDetails(this.properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
RestClientBuilder elasticsearchRestClientBuilder(
|
RestClientBuilderCustomizer defaultRestClientBuilderCustomizer(
|
||||||
|
ElasticsearchConnectionDetails connectionDetails) {
|
||||||
|
return new DefaultRestClientBuilderCustomizer(this.properties, connectionDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RestClientBuilder elasticsearchRestClientBuilder(ElasticsearchConnectionDetails connectionDetails,
|
||||||
ObjectProvider<RestClientBuilderCustomizer> builderCustomizers) {
|
ObjectProvider<RestClientBuilderCustomizer> builderCustomizers) {
|
||||||
RestClientBuilder builder = RestClient.builder(this.connectionDetails.getNodes()
|
RestClientBuilder builder = RestClient.builder(connectionDetails.getNodes()
|
||||||
.stream()
|
.stream()
|
||||||
.map((node) -> new HttpHost(node.hostname(), node.port(), node.protocol().getScheme()))
|
.map((node) -> new HttpHost(node.hostname(), node.port(), node.protocol().getScheme()))
|
||||||
.toArray(HttpHost[]::new));
|
.toArray(HttpHost[]::new));
|
||||||
@ -91,7 +94,7 @@ class ElasticsearchRestClientConfigurations {
|
|||||||
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(requestConfigBuilder));
|
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(requestConfigBuilder));
|
||||||
return requestConfigBuilder;
|
return requestConfigBuilder;
|
||||||
});
|
});
|
||||||
String pathPrefix = this.connectionDetails.getPathPrefix();
|
String pathPrefix = connectionDetails.getPathPrefix();
|
||||||
if (pathPrefix != null) {
|
if (pathPrefix != null) {
|
||||||
builder.setPathPrefix(pathPrefix);
|
builder.setPathPrefix(pathPrefix);
|
||||||
}
|
}
|
||||||
@ -212,7 +215,7 @@ class ElasticsearchRestClientConfigurations {
|
|||||||
/**
|
/**
|
||||||
* Adapts {@link ElasticsearchProperties} to {@link ElasticsearchConnectionDetails}.
|
* Adapts {@link ElasticsearchProperties} to {@link ElasticsearchConnectionDetails}.
|
||||||
*/
|
*/
|
||||||
private static class PropertiesElasticsearchConnectionDetails implements ElasticsearchConnectionDetails {
|
static class PropertiesElasticsearchConnectionDetails implements ElasticsearchConnectionDetails {
|
||||||
|
|
||||||
private final ElasticsearchProperties properties;
|
private final ElasticsearchProperties properties;
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
@ -121,27 +122,31 @@ public class FlywayAutoConfiguration {
|
|||||||
return new ResourceProviderCustomizer();
|
return new ResourceProviderCustomizer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(FlywayConnectionDetails.class)
|
||||||
|
PropertiesFlywayConnectionDetails flywayConnectionDetails(FlywayProperties properties,
|
||||||
|
ObjectProvider<JdbcConnectionDetails> jdbcConnectionDetails) {
|
||||||
|
return new PropertiesFlywayConnectionDetails(properties, jdbcConnectionDetails.getIfAvailable());
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||||
public Flyway flyway(FlywayProperties properties, ResourceLoader resourceLoader,
|
public Flyway flyway(FlywayProperties properties, ResourceLoader resourceLoader,
|
||||||
ObjectProvider<DataSource> dataSource, ObjectProvider<DataSource> flywayDataSource,
|
ObjectProvider<DataSource> dataSource, ObjectProvider<DataSource> flywayDataSource,
|
||||||
ObjectProvider<FlywayConfigurationCustomizer> fluentConfigurationCustomizers,
|
ObjectProvider<FlywayConfigurationCustomizer> fluentConfigurationCustomizers,
|
||||||
ObjectProvider<JavaMigration> javaMigrations, ObjectProvider<Callback> callbacks) {
|
ObjectProvider<JavaMigration> javaMigrations, ObjectProvider<Callback> callbacks) {
|
||||||
return flyway(properties, resourceLoader, dataSource, flywayDataSource, fluentConfigurationCustomizers,
|
return flyway(properties, new PropertiesFlywayConnectionDetails(properties, null), resourceLoader,
|
||||||
javaMigrations, callbacks, new ResourceProviderCustomizer(), null);
|
dataSource, flywayDataSource, fluentConfigurationCustomizers, javaMigrations, callbacks,
|
||||||
|
new ResourceProviderCustomizer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
Flyway flyway(FlywayProperties properties, ResourceLoader resourceLoader, ObjectProvider<DataSource> dataSource,
|
Flyway flyway(FlywayProperties properties, FlywayConnectionDetails connectionDetails,
|
||||||
|
ResourceLoader resourceLoader, ObjectProvider<DataSource> dataSource,
|
||||||
@FlywayDataSource ObjectProvider<DataSource> flywayDataSource,
|
@FlywayDataSource ObjectProvider<DataSource> flywayDataSource,
|
||||||
ObjectProvider<FlywayConfigurationCustomizer> fluentConfigurationCustomizers,
|
ObjectProvider<FlywayConfigurationCustomizer> fluentConfigurationCustomizers,
|
||||||
ObjectProvider<JavaMigration> javaMigrations, ObjectProvider<Callback> callbacks,
|
ObjectProvider<JavaMigration> javaMigrations, ObjectProvider<Callback> callbacks,
|
||||||
ResourceProviderCustomizer resourceProviderCustomizer,
|
ResourceProviderCustomizer resourceProviderCustomizer) {
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
|
||||||
FluentConfiguration configuration = new FluentConfiguration(resourceLoader.getClassLoader());
|
FluentConfiguration configuration = new FluentConfiguration(resourceLoader.getClassLoader());
|
||||||
JdbcConnectionDetails connectionDetails = (connectionDetailsProvider != null)
|
|
||||||
? connectionDetailsProvider.getIfAvailable() : null;
|
|
||||||
connectionDetails = (connectionDetails != null) ? connectionDetails
|
|
||||||
: new FlywayPropertiesJdbcConnectionDetails(properties);
|
|
||||||
configureDataSource(configuration, flywayDataSource.getIfAvailable(), dataSource.getIfUnique(),
|
configureDataSource(configuration, flywayDataSource.getIfAvailable(), dataSource.getIfUnique(),
|
||||||
connectionDetails);
|
connectionDetails);
|
||||||
configureProperties(configuration, properties);
|
configureProperties(configuration, properties);
|
||||||
@ -153,13 +158,13 @@ public class FlywayAutoConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void configureDataSource(FluentConfiguration configuration, DataSource flywayDataSource,
|
private void configureDataSource(FluentConfiguration configuration, DataSource flywayDataSource,
|
||||||
DataSource dataSource, JdbcConnectionDetails connectionDetails) {
|
DataSource dataSource, FlywayConnectionDetails connectionDetails) {
|
||||||
DataSource migrationDataSource = getMigrationDataSource(flywayDataSource, dataSource, connectionDetails);
|
DataSource migrationDataSource = getMigrationDataSource(flywayDataSource, dataSource, connectionDetails);
|
||||||
configuration.dataSource(migrationDataSource);
|
configuration.dataSource(migrationDataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataSource getMigrationDataSource(DataSource flywayDataSource, DataSource dataSource,
|
private DataSource getMigrationDataSource(DataSource flywayDataSource, DataSource dataSource,
|
||||||
JdbcConnectionDetails connectionDetails) {
|
FlywayConnectionDetails connectionDetails) {
|
||||||
if (flywayDataSource != null) {
|
if (flywayDataSource != null) {
|
||||||
return flywayDataSource;
|
return flywayDataSource;
|
||||||
}
|
}
|
||||||
@ -181,7 +186,7 @@ public class FlywayAutoConfiguration {
|
|||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyConnectionDetails(JdbcConnectionDetails connectionDetails, DataSourceBuilder<?> builder) {
|
private void applyConnectionDetails(FlywayConnectionDetails connectionDetails, DataSourceBuilder<?> builder) {
|
||||||
builder.username(connectionDetails.getUsername());
|
builder.username(connectionDetails.getUsername());
|
||||||
builder.password(connectionDetails.getPassword());
|
builder.password(connectionDetails.getPassword());
|
||||||
String driverClassName = connectionDetails.getDriverClassName();
|
String driverClassName = connectionDetails.getDriverClassName();
|
||||||
@ -406,34 +411,46 @@ public class FlywayAutoConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapts {@link FlywayProperties} to {@link JdbcConnectionDetails}.
|
* Adapts {@link FlywayProperties} to {@link FlywayConnectionDetails}, using
|
||||||
|
* {@link JdbcConnectionDetails} as a fallback when Flyway-specific properties have
|
||||||
|
* not be configured.
|
||||||
*/
|
*/
|
||||||
private static final class FlywayPropertiesJdbcConnectionDetails implements JdbcConnectionDetails {
|
static final class PropertiesFlywayConnectionDetails implements FlywayConnectionDetails {
|
||||||
|
|
||||||
|
private final JdbcConnectionDetails fallback;
|
||||||
|
|
||||||
private final FlywayProperties properties;
|
private final FlywayProperties properties;
|
||||||
|
|
||||||
private FlywayPropertiesJdbcConnectionDetails(FlywayProperties properties) {
|
PropertiesFlywayConnectionDetails(FlywayProperties properties, JdbcConnectionDetails fallback) {
|
||||||
|
this.fallback = fallback;
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return this.properties.getUser();
|
return get(this.properties.getUser(), JdbcConnectionDetails::getUsername);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
return this.properties.getPassword();
|
return get(this.properties.getPassword(), JdbcConnectionDetails::getPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getJdbcUrl() {
|
public String getJdbcUrl() {
|
||||||
return this.properties.getUrl();
|
return get(this.properties.getUrl(), JdbcConnectionDetails::getJdbcUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDriverClassName() {
|
public String getDriverClassName() {
|
||||||
return this.properties.getDriverClassName();
|
return get(this.properties.getDriverClassName(), JdbcConnectionDetails::getDriverClassName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String get(String primary, Function<JdbcConnectionDetails, String> fallbackProperty) {
|
||||||
|
if (primary != null) {
|
||||||
|
return primary;
|
||||||
|
}
|
||||||
|
return (this.fallback != null) ? fallbackProperty.apply(this.fallback) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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.flyway;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||||
|
import org.springframework.boot.jdbc.DatabaseDriver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Details required for Flyway to establish a connection to an SQL service using JDBC.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
public interface FlywayConnectionDetails extends ConnectionDetails {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Username for the database.
|
||||||
|
* @return the username for the database
|
||||||
|
*/
|
||||||
|
String getUsername();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password for the database.
|
||||||
|
* @return the password for the database
|
||||||
|
*/
|
||||||
|
String getPassword();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JDBC URL for the database.
|
||||||
|
* @return the JDBC URL for the database
|
||||||
|
*/
|
||||||
|
String getJdbcUrl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the JDBC driver class. Defaults to the class name of the driver
|
||||||
|
* specified in the JDBC URL.
|
||||||
|
* @return the JDBC driver class name
|
||||||
|
* @see #getJdbcUrl()
|
||||||
|
* @see DatabaseDriver#fromJdbcUrl(String)
|
||||||
|
* @see DatabaseDriver#getDriverClassName()
|
||||||
|
*/
|
||||||
|
default String getDriverClassName() {
|
||||||
|
return DatabaseDriver.fromJdbcUrl(getJdbcUrl()).getDriverClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
|||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration.InfluxDBCondition;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Condition;
|
import org.springframework.context.annotation.Condition;
|
||||||
@ -48,17 +49,21 @@ import org.springframework.context.annotation.Conditional;
|
|||||||
*/
|
*/
|
||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
@ConditionalOnClass(InfluxDB.class)
|
@ConditionalOnClass(InfluxDB.class)
|
||||||
|
@Conditional(InfluxDBCondition.class)
|
||||||
@EnableConfigurationProperties(InfluxDbProperties.class)
|
@EnableConfigurationProperties(InfluxDbProperties.class)
|
||||||
public class InfluxDbAutoConfiguration {
|
public class InfluxDbAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(InfluxDbConnectionDetails.class)
|
||||||
|
PropertiesInfluxDbConnectionDetails influxDbConnectionDetails(InfluxDbProperties properties) {
|
||||||
|
return new PropertiesInfluxDbConnectionDetails(properties);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
@Conditional(InfluxDBCondition.class)
|
public InfluxDB influxDb(InfluxDbConnectionDetails connectionDetails,
|
||||||
public InfluxDB influxDb(InfluxDbProperties properties, ObjectProvider<InfluxDbOkHttpClientBuilderProvider> builder,
|
ObjectProvider<InfluxDbOkHttpClientBuilderProvider> builder,
|
||||||
ObjectProvider<InfluxDbCustomizer> customizers,
|
ObjectProvider<InfluxDbCustomizer> customizers) {
|
||||||
ObjectProvider<InfluxDbConnectionDetails> connectionDetailsProvider) {
|
|
||||||
InfluxDbConnectionDetails connectionDetails = connectionDetailsProvider
|
|
||||||
.getIfAvailable(() -> new PropertiesInfluxDbConnectionDetails(properties));
|
|
||||||
InfluxDB influxDb = new InfluxDBImpl(connectionDetails.getUrl().toString(), connectionDetails.getUsername(),
|
InfluxDB influxDb = new InfluxDBImpl(connectionDetails.getUrl().toString(), connectionDetails.getUsername(),
|
||||||
connectionDetails.getPassword(), determineBuilder(builder.getIfAvailable()));
|
connectionDetails.getPassword(), determineBuilder(builder.getIfAvailable()));
|
||||||
customizers.orderedStream().forEach((customizer) -> customizer.customize(influxDb));
|
customizers.orderedStream().forEach((customizer) -> customizer.customize(influxDb));
|
||||||
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -33,6 +33,7 @@ import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConf
|
|||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||||
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
|
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Condition;
|
import org.springframework.context.annotation.Condition;
|
||||||
import org.springframework.context.annotation.ConditionContext;
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
import org.springframework.context.annotation.Conditional;
|
import org.springframework.context.annotation.Conditional;
|
||||||
@ -75,6 +76,12 @@ public class DataSourceAutoConfiguration {
|
|||||||
DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })
|
DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })
|
||||||
protected static class PooledDataSourceConfiguration {
|
protected static class PooledDataSourceConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(JdbcConnectionDetails.class)
|
||||||
|
PropertiesJdbcConnectionDetails jdbcConnectionDetails(DataSourceProperties properties) {
|
||||||
|
return new PropertiesJdbcConnectionDetails(properties);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,6 @@ import oracle.jdbc.OracleConnection;
|
|||||||
import oracle.ucp.jdbc.PoolDataSourceImpl;
|
import oracle.ucp.jdbc.PoolDataSourceImpl;
|
||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
@ -48,20 +47,15 @@ import org.springframework.util.StringUtils;
|
|||||||
*/
|
*/
|
||||||
abstract class DataSourceConfiguration {
|
abstract class DataSourceConfiguration {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) {
|
|
||||||
return (T) properties.initializeDataSourceBuilder().type(type).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private static <T> T createDataSource(JdbcConnectionDetails connectionDetails, Class<? extends DataSource> type,
|
private static <T> T createDataSource(JdbcConnectionDetails connectionDetails, Class<? extends DataSource> type,
|
||||||
ClassLoader classLoader) {
|
ClassLoader classLoader) {
|
||||||
return (T) DataSourceBuilder.create(classLoader)
|
return (T) DataSourceBuilder.create(classLoader)
|
||||||
|
.type(type)
|
||||||
|
.driverClassName(connectionDetails.getDriverClassName())
|
||||||
.url(connectionDetails.getJdbcUrl())
|
.url(connectionDetails.getJdbcUrl())
|
||||||
.username(connectionDetails.getUsername())
|
.username(connectionDetails.getUsername())
|
||||||
.password(connectionDetails.getPassword())
|
.password(connectionDetails.getPassword())
|
||||||
.driverClassName(connectionDetails.getDriverClassName())
|
|
||||||
.type(type)
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +70,7 @@ abstract class DataSourceConfiguration {
|
|||||||
static class Tomcat {
|
static class Tomcat {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnBean(JdbcConnectionDetails.class)
|
@ConditionalOnMissingBean(PropertiesJdbcConnectionDetails.class)
|
||||||
static TomcatJdbcConnectionDetailsBeanPostProcessor tomcatJdbcConnectionDetailsBeanPostProcessor(
|
static TomcatJdbcConnectionDetailsBeanPostProcessor tomcatJdbcConnectionDetailsBeanPostProcessor(
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
||||||
return new TomcatJdbcConnectionDetailsBeanPostProcessor(connectionDetailsProvider);
|
return new TomcatJdbcConnectionDetailsBeanPostProcessor(connectionDetailsProvider);
|
||||||
@ -85,15 +79,12 @@ abstract class DataSourceConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConfigurationProperties(prefix = "spring.datasource.tomcat")
|
@ConfigurationProperties(prefix = "spring.datasource.tomcat")
|
||||||
org.apache.tomcat.jdbc.pool.DataSource dataSource(DataSourceProperties properties,
|
org.apache.tomcat.jdbc.pool.DataSource dataSource(DataSourceProperties properties,
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
JdbcConnectionDetails connectionDetails) {
|
||||||
JdbcConnectionDetails connectionDetails = connectionDetailsProvider.getIfAvailable();
|
|
||||||
Class<? extends DataSource> dataSourceType = org.apache.tomcat.jdbc.pool.DataSource.class;
|
Class<? extends DataSource> dataSourceType = org.apache.tomcat.jdbc.pool.DataSource.class;
|
||||||
org.apache.tomcat.jdbc.pool.DataSource dataSource = (connectionDetails != null)
|
org.apache.tomcat.jdbc.pool.DataSource dataSource = createDataSource(connectionDetails, dataSourceType,
|
||||||
? createDataSource(connectionDetails, dataSourceType, properties.getClassLoader())
|
properties.getClassLoader());
|
||||||
: createDataSource(properties, dataSourceType);
|
|
||||||
String validationQuery;
|
String validationQuery;
|
||||||
String url = (connectionDetails != null) ? connectionDetails.getJdbcUrl() : properties.determineUrl();
|
DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(connectionDetails.getJdbcUrl());
|
||||||
DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(url);
|
|
||||||
validationQuery = databaseDriver.getValidationQuery();
|
validationQuery = databaseDriver.getValidationQuery();
|
||||||
if (validationQuery != null) {
|
if (validationQuery != null) {
|
||||||
dataSource.setTestOnBorrow(true);
|
dataSource.setTestOnBorrow(true);
|
||||||
@ -115,7 +106,6 @@ abstract class DataSourceConfiguration {
|
|||||||
static class Hikari {
|
static class Hikari {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnBean(JdbcConnectionDetails.class)
|
|
||||||
static HikariJdbcConnectionDetailsBeanPostProcessor jdbcConnectionDetailsHikariBeanPostProcessor(
|
static HikariJdbcConnectionDetailsBeanPostProcessor jdbcConnectionDetailsHikariBeanPostProcessor(
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
||||||
return new HikariJdbcConnectionDetailsBeanPostProcessor(connectionDetailsProvider);
|
return new HikariJdbcConnectionDetailsBeanPostProcessor(connectionDetailsProvider);
|
||||||
@ -123,12 +113,9 @@ abstract class DataSourceConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConfigurationProperties(prefix = "spring.datasource.hikari")
|
@ConfigurationProperties(prefix = "spring.datasource.hikari")
|
||||||
HikariDataSource dataSource(DataSourceProperties properties,
|
HikariDataSource dataSource(DataSourceProperties properties, JdbcConnectionDetails connectionDetails) {
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
HikariDataSource dataSource = createDataSource(connectionDetails, HikariDataSource.class,
|
||||||
JdbcConnectionDetails connectionDetails = connectionDetailsProvider.getIfAvailable();
|
properties.getClassLoader());
|
||||||
HikariDataSource dataSource = (connectionDetails != null)
|
|
||||||
? createDataSource(connectionDetails, HikariDataSource.class, properties.getClassLoader())
|
|
||||||
: createDataSource(properties, HikariDataSource.class);
|
|
||||||
if (StringUtils.hasText(properties.getName())) {
|
if (StringUtils.hasText(properties.getName())) {
|
||||||
dataSource.setPoolName(properties.getName());
|
dataSource.setPoolName(properties.getName());
|
||||||
}
|
}
|
||||||
@ -148,7 +135,6 @@ abstract class DataSourceConfiguration {
|
|||||||
static class Dbcp2 {
|
static class Dbcp2 {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnBean(JdbcConnectionDetails.class)
|
|
||||||
static Dbcp2JdbcConnectionDetailsBeanPostProcessor dbcp2JdbcConnectionDetailsBeanPostProcessor(
|
static Dbcp2JdbcConnectionDetailsBeanPostProcessor dbcp2JdbcConnectionDetailsBeanPostProcessor(
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
||||||
return new Dbcp2JdbcConnectionDetailsBeanPostProcessor(connectionDetailsProvider);
|
return new Dbcp2JdbcConnectionDetailsBeanPostProcessor(connectionDetailsProvider);
|
||||||
@ -157,12 +143,9 @@ abstract class DataSourceConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConfigurationProperties(prefix = "spring.datasource.dbcp2")
|
@ConfigurationProperties(prefix = "spring.datasource.dbcp2")
|
||||||
org.apache.commons.dbcp2.BasicDataSource dataSource(DataSourceProperties properties,
|
org.apache.commons.dbcp2.BasicDataSource dataSource(DataSourceProperties properties,
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
JdbcConnectionDetails connectionDetails) {
|
||||||
JdbcConnectionDetails connectionDetails = connectionDetailsProvider.getIfAvailable();
|
|
||||||
Class<? extends DataSource> dataSourceType = org.apache.commons.dbcp2.BasicDataSource.class;
|
Class<? extends DataSource> dataSourceType = org.apache.commons.dbcp2.BasicDataSource.class;
|
||||||
return (connectionDetails != null)
|
return createDataSource(connectionDetails, dataSourceType, properties.getClassLoader());
|
||||||
? createDataSource(connectionDetails, dataSourceType, properties.getClassLoader())
|
|
||||||
: createDataSource(properties, dataSourceType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -178,7 +161,6 @@ abstract class DataSourceConfiguration {
|
|||||||
static class OracleUcp {
|
static class OracleUcp {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnBean(JdbcConnectionDetails.class)
|
|
||||||
static OracleUcpJdbcConnectionDetailsBeanPostProcessor oracleUcpJdbcConnectionDetailsBeanPostProcessor(
|
static OracleUcpJdbcConnectionDetailsBeanPostProcessor oracleUcpJdbcConnectionDetailsBeanPostProcessor(
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
||||||
return new OracleUcpJdbcConnectionDetailsBeanPostProcessor(connectionDetailsProvider);
|
return new OracleUcpJdbcConnectionDetailsBeanPostProcessor(connectionDetailsProvider);
|
||||||
@ -186,12 +168,10 @@ abstract class DataSourceConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConfigurationProperties(prefix = "spring.datasource.oracleucp")
|
@ConfigurationProperties(prefix = "spring.datasource.oracleucp")
|
||||||
PoolDataSourceImpl dataSource(DataSourceProperties properties,
|
PoolDataSourceImpl dataSource(DataSourceProperties properties, JdbcConnectionDetails connectionDetails)
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) throws SQLException {
|
throws SQLException {
|
||||||
JdbcConnectionDetails connectionDetails = connectionDetailsProvider.getIfAvailable();
|
PoolDataSourceImpl dataSource = createDataSource(connectionDetails, PoolDataSourceImpl.class,
|
||||||
PoolDataSourceImpl dataSource = (connectionDetails != null)
|
properties.getClassLoader());
|
||||||
? createDataSource(connectionDetails, PoolDataSourceImpl.class, properties.getClassLoader())
|
|
||||||
: createDataSource(properties, PoolDataSourceImpl.class);
|
|
||||||
dataSource.setValidateConnectionOnBorrow(true);
|
dataSource.setValidateConnectionOnBorrow(true);
|
||||||
if (StringUtils.hasText(properties.getName())) {
|
if (StringUtils.hasText(properties.getName())) {
|
||||||
dataSource.setConnectionPoolName(properties.getName());
|
dataSource.setConnectionPoolName(properties.getName());
|
||||||
@ -210,14 +190,9 @@ abstract class DataSourceConfiguration {
|
|||||||
static class Generic {
|
static class Generic {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
DataSource dataSource(DataSourceProperties properties,
|
DataSource dataSource(DataSourceProperties properties, JdbcConnectionDetails connectionDetails) {
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
|
|
||||||
JdbcConnectionDetails connectionDetails = connectionDetailsProvider.getIfAvailable();
|
|
||||||
if (connectionDetails != null) {
|
|
||||||
return createDataSource(connectionDetails, properties.getType(), properties.getClassLoader());
|
return createDataSource(connectionDetails, properties.getType(), properties.getClassLoader());
|
||||||
}
|
}
|
||||||
return properties.initializeDataSourceBuilder().build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ import org.springframework.boot.jdbc.DatabaseDriver;
|
|||||||
public interface JdbcConnectionDetails extends ConnectionDetails {
|
public interface JdbcConnectionDetails extends ConnectionDetails {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hostname for the database.
|
* Username for the database.
|
||||||
* @return the username for the database
|
* @return the username for the database
|
||||||
*/
|
*/
|
||||||
String getUsername();
|
String getUsername();
|
||||||
|
@ -24,7 +24,10 @@ import org.springframework.core.PriorityOrdered;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for DataSource bean post processors which apply values from
|
* Abstract base class for DataSource bean post processors which apply values from
|
||||||
* {@link JdbcConnectionDetails}. Acts on beans named 'dataSource' of type {@code T}.
|
* {@link JdbcConnectionDetails}. Property-based connection details
|
||||||
|
* ({@link PropertiesJdbcConnectionDetails} are ignored as the expectation is that they
|
||||||
|
* will have already been applied by configuration property binding. Acts on beans named
|
||||||
|
* 'dataSource' of type {@code T}.
|
||||||
*
|
*
|
||||||
* @param <T> type of the datasource
|
* @param <T> type of the datasource
|
||||||
* @author Moritz Halbritter
|
* @author Moritz Halbritter
|
||||||
@ -48,8 +51,10 @@ abstract class JdbcConnectionDetailsBeanPostProcessor<T> implements BeanPostProc
|
|||||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||||
if (this.dataSourceClass.isAssignableFrom(bean.getClass()) && "dataSource".equals(beanName)) {
|
if (this.dataSourceClass.isAssignableFrom(bean.getClass()) && "dataSource".equals(beanName)) {
|
||||||
JdbcConnectionDetails connectionDetails = this.connectionDetailsProvider.getObject();
|
JdbcConnectionDetails connectionDetails = this.connectionDetailsProvider.getObject();
|
||||||
|
if (!(connectionDetails instanceof PropertiesJdbcConnectionDetails)) {
|
||||||
return processDataSource((T) bean, connectionDetails);
|
return processDataSource((T) bean, connectionDetails);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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.jdbc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapts {@link DataSourceProperties} to {@link JdbcConnectionDetails}.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
*/
|
||||||
|
final class PropertiesJdbcConnectionDetails implements JdbcConnectionDetails {
|
||||||
|
|
||||||
|
private final DataSourceProperties properties;
|
||||||
|
|
||||||
|
PropertiesJdbcConnectionDetails(DataSourceProperties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return this.properties.determineUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return this.properties.determinePassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJdbcUrl() {
|
||||||
|
return this.properties.determineUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDriverClassName() {
|
||||||
|
return this.properties.determineDriverClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getXaDataSourceClassName() {
|
||||||
|
return (this.properties.getXa().getDataSourceClassName() != null)
|
||||||
|
? this.properties.getXa().getDataSourceClassName()
|
||||||
|
: JdbcConnectionDetails.super.getXaDataSourceClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -66,12 +66,17 @@ public class XADataSourceAutoConfiguration implements BeanClassLoaderAware {
|
|||||||
|
|
||||||
private ClassLoader classLoader;
|
private ClassLoader classLoader;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(JdbcConnectionDetails.class)
|
||||||
|
PropertiesJdbcConnectionDetails jdbcConnectionDetails(DataSourceProperties properties) {
|
||||||
|
return new PropertiesJdbcConnectionDetails(properties);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public DataSource dataSource(XADataSourceWrapper wrapper, DataSourceProperties properties,
|
public DataSource dataSource(XADataSourceWrapper wrapper, DataSourceProperties properties,
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetails, ObjectProvider<XADataSource> xaDataSource)
|
JdbcConnectionDetails connectionDetails, ObjectProvider<XADataSource> xaDataSource) throws Exception {
|
||||||
throws Exception {
|
return wrapper
|
||||||
return wrapper.wrapDataSource(xaDataSource.getIfAvailable(() -> createXaDataSource(properties,
|
.wrapDataSource(xaDataSource.getIfAvailable(() -> createXaDataSource(properties, connectionDetails)));
|
||||||
connectionDetails.getIfAvailable(() -> new PropertiesJdbcConnectionDetails(properties)))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -122,45 +127,4 @@ public class XADataSourceAutoConfiguration implements BeanClassLoaderAware {
|
|||||||
return source.withAliases(aliases);
|
return source.withAliases(aliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapts {@link DataSourceProperties} to {@link JdbcConnectionDetails}.
|
|
||||||
*/
|
|
||||||
private static class PropertiesJdbcConnectionDetails implements JdbcConnectionDetails {
|
|
||||||
|
|
||||||
private final DataSourceProperties properties;
|
|
||||||
|
|
||||||
PropertiesJdbcConnectionDetails(DataSourceProperties properties) {
|
|
||||||
this.properties = properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsername() {
|
|
||||||
return this.properties.determineUsername();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPassword() {
|
|
||||||
return this.properties.determinePassword();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getJdbcUrl() {
|
|
||||||
return this.properties.determineUrl();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDriverClassName() {
|
|
||||||
return (this.properties.getDriverClassName() != null) ? this.properties.getDriverClassName()
|
|
||||||
: JdbcConnectionDetails.super.getDriverClassName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getXaDataSourceClassName() {
|
|
||||||
return (this.properties.getXa().getDataSourceClassName() != null)
|
|
||||||
? this.properties.getXa().getDataSourceClassName()
|
|
||||||
: JdbcConnectionDetails.super.getXaDataSourceClassName();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -76,12 +76,14 @@ public class KafkaAutoConfiguration {
|
|||||||
|
|
||||||
private final KafkaProperties properties;
|
private final KafkaProperties properties;
|
||||||
|
|
||||||
private final KafkaConnectionDetails connectionDetails;
|
KafkaAutoConfiguration(KafkaProperties properties) {
|
||||||
|
|
||||||
KafkaAutoConfiguration(KafkaProperties properties, ObjectProvider<KafkaConnectionDetails> connectionDetails) {
|
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.connectionDetails = connectionDetails
|
}
|
||||||
.getIfAvailable(() -> new PropertiesKafkaConnectionDetails(properties));
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(KafkaConnectionDetails.class)
|
||||||
|
PropertiesKafkaConnectionDetails kafkaConnectionDetails(KafkaProperties properties) {
|
||||||
|
return new PropertiesKafkaConnectionDetails(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ -106,10 +108,10 @@ public class KafkaAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(ConsumerFactory.class)
|
@ConditionalOnMissingBean(ConsumerFactory.class)
|
||||||
public DefaultKafkaConsumerFactory<?, ?> kafkaConsumerFactory(
|
public DefaultKafkaConsumerFactory<?, ?> kafkaConsumerFactory(KafkaConnectionDetails connectionDetails,
|
||||||
ObjectProvider<DefaultKafkaConsumerFactoryCustomizer> customizers) {
|
ObjectProvider<DefaultKafkaConsumerFactoryCustomizer> customizers) {
|
||||||
Map<String, Object> properties = this.properties.buildConsumerProperties();
|
Map<String, Object> properties = this.properties.buildConsumerProperties();
|
||||||
applyKafkaConnectionDetailsForConsumer(properties);
|
applyKafkaConnectionDetailsForConsumer(properties, connectionDetails);
|
||||||
DefaultKafkaConsumerFactory<Object, Object> factory = new DefaultKafkaConsumerFactory<>(properties);
|
DefaultKafkaConsumerFactory<Object, Object> factory = new DefaultKafkaConsumerFactory<>(properties);
|
||||||
customizers.orderedStream().forEach((customizer) -> customizer.customize(factory));
|
customizers.orderedStream().forEach((customizer) -> customizer.customize(factory));
|
||||||
return factory;
|
return factory;
|
||||||
@ -117,10 +119,10 @@ public class KafkaAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(ProducerFactory.class)
|
@ConditionalOnMissingBean(ProducerFactory.class)
|
||||||
public DefaultKafkaProducerFactory<?, ?> kafkaProducerFactory(
|
public DefaultKafkaProducerFactory<?, ?> kafkaProducerFactory(KafkaConnectionDetails connectionDetails,
|
||||||
ObjectProvider<DefaultKafkaProducerFactoryCustomizer> customizers) {
|
ObjectProvider<DefaultKafkaProducerFactoryCustomizer> customizers) {
|
||||||
Map<String, Object> properties = this.properties.buildProducerProperties();
|
Map<String, Object> properties = this.properties.buildProducerProperties();
|
||||||
applyKafkaConnectionDetailsForProducer(properties);
|
applyKafkaConnectionDetailsForProducer(properties, connectionDetails);
|
||||||
DefaultKafkaProducerFactory<?, ?> factory = new DefaultKafkaProducerFactory<>(properties);
|
DefaultKafkaProducerFactory<?, ?> factory = new DefaultKafkaProducerFactory<>(properties);
|
||||||
String transactionIdPrefix = this.properties.getProducer().getTransactionIdPrefix();
|
String transactionIdPrefix = this.properties.getProducer().getTransactionIdPrefix();
|
||||||
if (transactionIdPrefix != null) {
|
if (transactionIdPrefix != null) {
|
||||||
@ -155,9 +157,9 @@ public class KafkaAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public KafkaAdmin kafkaAdmin() {
|
public KafkaAdmin kafkaAdmin(KafkaConnectionDetails connectionDetails) {
|
||||||
Map<String, Object> properties = this.properties.buildAdminProperties();
|
Map<String, Object> properties = this.properties.buildAdminProperties();
|
||||||
applyKafkaConnectionDetailsForAdmin(properties);
|
applyKafkaConnectionDetailsForAdmin(properties, connectionDetails);
|
||||||
KafkaAdmin kafkaAdmin = new KafkaAdmin(properties);
|
KafkaAdmin kafkaAdmin = new KafkaAdmin(properties);
|
||||||
KafkaProperties.Admin admin = this.properties.getAdmin();
|
KafkaProperties.Admin admin = this.properties.getAdmin();
|
||||||
if (admin.getCloseTimeout() != null) {
|
if (admin.getCloseTimeout() != null) {
|
||||||
@ -186,26 +188,29 @@ public class KafkaAutoConfiguration {
|
|||||||
return builder.create(kafkaTemplate);
|
return builder.create(kafkaTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyKafkaConnectionDetailsForConsumer(Map<String, Object> properties) {
|
private void applyKafkaConnectionDetailsForConsumer(Map<String, Object> properties,
|
||||||
|
KafkaConnectionDetails connectionDetails) {
|
||||||
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
|
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
|
||||||
nodesToStringList(this.connectionDetails.getConsumerBootstrapNodes()));
|
nodesToStringList(connectionDetails.getConsumerBootstrapNodes()));
|
||||||
if (!(this.connectionDetails instanceof PropertiesKafkaConnectionDetails)) {
|
if (!(connectionDetails instanceof PropertiesKafkaConnectionDetails)) {
|
||||||
properties.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "PLAINTEXT");
|
properties.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "PLAINTEXT");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyKafkaConnectionDetailsForProducer(Map<String, Object> properties) {
|
private void applyKafkaConnectionDetailsForProducer(Map<String, Object> properties,
|
||||||
|
KafkaConnectionDetails connectionDetails) {
|
||||||
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,
|
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,
|
||||||
nodesToStringList(this.connectionDetails.getProducerBootstrapNodes()));
|
nodesToStringList(connectionDetails.getProducerBootstrapNodes()));
|
||||||
if (!(this.connectionDetails instanceof PropertiesKafkaConnectionDetails)) {
|
if (!(connectionDetails instanceof PropertiesKafkaConnectionDetails)) {
|
||||||
properties.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "PLAINTEXT");
|
properties.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "PLAINTEXT");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyKafkaConnectionDetailsForAdmin(Map<String, Object> properties) {
|
private void applyKafkaConnectionDetailsForAdmin(Map<String, Object> properties,
|
||||||
|
KafkaConnectionDetails connectionDetails) {
|
||||||
properties.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG,
|
properties.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG,
|
||||||
nodesToStringList(this.connectionDetails.getAdminBootstrapNodes()));
|
nodesToStringList(connectionDetails.getAdminBootstrapNodes()));
|
||||||
if (!(this.connectionDetails instanceof PropertiesKafkaConnectionDetails)) {
|
if (!(connectionDetails instanceof PropertiesKafkaConnectionDetails)) {
|
||||||
properties.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "PLAINTEXT");
|
properties.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "PLAINTEXT");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,11 +63,9 @@ class KafkaStreamsAnnotationDrivenConfiguration {
|
|||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
@Bean(KafkaStreamsDefaultConfiguration.DEFAULT_STREAMS_CONFIG_BEAN_NAME)
|
@Bean(KafkaStreamsDefaultConfiguration.DEFAULT_STREAMS_CONFIG_BEAN_NAME)
|
||||||
KafkaStreamsConfiguration defaultKafkaStreamsConfig(Environment environment,
|
KafkaStreamsConfiguration defaultKafkaStreamsConfig(Environment environment,
|
||||||
ObjectProvider<KafkaConnectionDetails> connectionDetailsProvider) {
|
KafkaConnectionDetails connectionDetails) {
|
||||||
KafkaConnectionDetails connectionDetails = connectionDetailsProvider
|
|
||||||
.getIfAvailable(() -> new PropertiesKafkaConnectionDetails(this.properties));
|
|
||||||
Map<String, Object> properties = this.properties.buildStreamsProperties();
|
Map<String, Object> properties = this.properties.buildStreamsProperties();
|
||||||
applyKafkaConnectionDetailsForStreams(connectionDetails, properties);
|
applyKafkaConnectionDetailsForStreams(properties, connectionDetails);
|
||||||
if (this.properties.getStreams().getApplicationId() == null) {
|
if (this.properties.getStreams().getApplicationId() == null) {
|
||||||
String applicationName = environment.getProperty("spring.application.name");
|
String applicationName = environment.getProperty("spring.application.name");
|
||||||
if (applicationName == null) {
|
if (applicationName == null) {
|
||||||
@ -87,8 +85,8 @@ class KafkaStreamsAnnotationDrivenConfiguration {
|
|||||||
return new KafkaStreamsFactoryBeanConfigurer(this.properties, factoryBean);
|
return new KafkaStreamsFactoryBeanConfigurer(this.properties, factoryBean);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyKafkaConnectionDetailsForStreams(KafkaConnectionDetails connectionDetails,
|
private void applyKafkaConnectionDetailsForStreams(Map<String, Object> properties,
|
||||||
Map<String, Object> properties) {
|
KafkaConnectionDetails connectionDetails) {
|
||||||
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
|
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
|
||||||
nodesToStringList(connectionDetails.getStreamsBootstrapNodes()));
|
nodesToStringList(connectionDetails.getStreamsBootstrapNodes()));
|
||||||
if (!(connectionDetails instanceof PropertiesKafkaConnectionDetails)) {
|
if (!(connectionDetails instanceof PropertiesKafkaConnectionDetails)) {
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.springframework.boot.autoconfigure.liquibase;
|
package org.springframework.boot.autoconfigure.liquibase;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import liquibase.change.DatabaseChange;
|
import liquibase.change.DatabaseChange;
|
||||||
@ -31,6 +33,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
|||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.autoconfigure.flyway.FlywayConnectionDetails;
|
||||||
|
import org.springframework.boot.autoconfigure.flyway.FlywayProperties;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
|
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
|
||||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseAutoConfigurationRuntimeHints;
|
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseAutoConfigurationRuntimeHints;
|
||||||
@ -85,13 +89,19 @@ public class LiquibaseAutoConfiguration {
|
|||||||
@EnableConfigurationProperties(LiquibaseProperties.class)
|
@EnableConfigurationProperties(LiquibaseProperties.class)
|
||||||
public static class LiquibaseConfiguration {
|
public static class LiquibaseConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(LiquibaseConnectionDetails.class)
|
||||||
|
PropertiesLiquibaseConnectionDetails liquibaseConnectionDetails(LiquibaseProperties properties,
|
||||||
|
ObjectProvider<JdbcConnectionDetails> jdbcConnectionDetails) {
|
||||||
|
return new PropertiesLiquibaseConnectionDetails(properties, jdbcConnectionDetails.getIfAvailable());
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SpringLiquibase liquibase(ObjectProvider<DataSource> dataSource,
|
public SpringLiquibase liquibase(ObjectProvider<DataSource> dataSource,
|
||||||
@LiquibaseDataSource ObjectProvider<DataSource> liquibaseDataSource, LiquibaseProperties properties,
|
@LiquibaseDataSource ObjectProvider<DataSource> liquibaseDataSource, LiquibaseProperties properties,
|
||||||
ObjectProvider<JdbcConnectionDetails> connectionDetails) {
|
LiquibaseConnectionDetails connectionDetails) {
|
||||||
SpringLiquibase liquibase = createSpringLiquibase(liquibaseDataSource.getIfAvailable(),
|
SpringLiquibase liquibase = createSpringLiquibase(liquibaseDataSource.getIfAvailable(),
|
||||||
dataSource.getIfUnique(),
|
dataSource.getIfUnique(), connectionDetails);
|
||||||
connectionDetails.getIfAvailable(() -> new LiquibasePropertiesJdbcConnectionDetails(properties)));
|
|
||||||
liquibase.setChangeLog(properties.getChangeLog());
|
liquibase.setChangeLog(properties.getChangeLog());
|
||||||
liquibase.setClearCheckSums(properties.isClearChecksums());
|
liquibase.setClearCheckSums(properties.isClearChecksums());
|
||||||
liquibase.setContexts(properties.getContexts());
|
liquibase.setContexts(properties.getContexts());
|
||||||
@ -111,7 +121,7 @@ public class LiquibaseAutoConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SpringLiquibase createSpringLiquibase(DataSource liquibaseDataSource, DataSource dataSource,
|
private SpringLiquibase createSpringLiquibase(DataSource liquibaseDataSource, DataSource dataSource,
|
||||||
JdbcConnectionDetails connectionDetails) {
|
LiquibaseConnectionDetails connectionDetails) {
|
||||||
DataSource migrationDataSource = getMigrationDataSource(liquibaseDataSource, dataSource, connectionDetails);
|
DataSource migrationDataSource = getMigrationDataSource(liquibaseDataSource, dataSource, connectionDetails);
|
||||||
SpringLiquibase liquibase = (migrationDataSource == liquibaseDataSource
|
SpringLiquibase liquibase = (migrationDataSource == liquibaseDataSource
|
||||||
|| migrationDataSource == dataSource) ? new SpringLiquibase()
|
|| migrationDataSource == dataSource) ? new SpringLiquibase()
|
||||||
@ -121,7 +131,7 @@ public class LiquibaseAutoConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private DataSource getMigrationDataSource(DataSource liquibaseDataSource, DataSource dataSource,
|
private DataSource getMigrationDataSource(DataSource liquibaseDataSource, DataSource dataSource,
|
||||||
JdbcConnectionDetails connectionDetails) {
|
LiquibaseConnectionDetails connectionDetails) {
|
||||||
if (liquibaseDataSource != null) {
|
if (liquibaseDataSource != null) {
|
||||||
return liquibaseDataSource;
|
return liquibaseDataSource;
|
||||||
}
|
}
|
||||||
@ -143,7 +153,8 @@ public class LiquibaseAutoConfiguration {
|
|||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyConnectionDetails(JdbcConnectionDetails connectionDetails, DataSourceBuilder<?> builder) {
|
private void applyConnectionDetails(LiquibaseConnectionDetails connectionDetails,
|
||||||
|
DataSourceBuilder<?> builder) {
|
||||||
builder.username(connectionDetails.getUsername());
|
builder.username(connectionDetails.getUsername());
|
||||||
builder.password(connectionDetails.getPassword());
|
builder.password(connectionDetails.getPassword());
|
||||||
String driverClassName = connectionDetails.getDriverClassName();
|
String driverClassName = connectionDetails.getDriverClassName();
|
||||||
@ -187,34 +198,46 @@ public class LiquibaseAutoConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapts {@link LiquibaseProperties} to {@link JdbcConnectionDetails}.
|
* Adapts {@link FlywayProperties} to {@link FlywayConnectionDetails}, using
|
||||||
|
* {@link JdbcConnectionDetails} as a fallback when Flyway-specific properties have
|
||||||
|
* not be configured.
|
||||||
*/
|
*/
|
||||||
private static final class LiquibasePropertiesJdbcConnectionDetails implements JdbcConnectionDetails {
|
static final class PropertiesLiquibaseConnectionDetails implements LiquibaseConnectionDetails {
|
||||||
|
|
||||||
|
private final JdbcConnectionDetails fallback;
|
||||||
|
|
||||||
private final LiquibaseProperties properties;
|
private final LiquibaseProperties properties;
|
||||||
|
|
||||||
private LiquibasePropertiesJdbcConnectionDetails(LiquibaseProperties properties) {
|
PropertiesLiquibaseConnectionDetails(LiquibaseProperties properties, JdbcConnectionDetails fallback) {
|
||||||
|
this.fallback = fallback;
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return this.properties.getUser();
|
return get(this.properties.getUser(), JdbcConnectionDetails::getUsername);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
return this.properties.getPassword();
|
return get(this.properties.getPassword(), JdbcConnectionDetails::getPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getJdbcUrl() {
|
public String getJdbcUrl() {
|
||||||
return this.properties.getUrl();
|
return get(this.properties.getUrl(), JdbcConnectionDetails::getJdbcUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDriverClassName() {
|
public String getDriverClassName() {
|
||||||
return this.properties.getDriverClassName();
|
return get(this.properties.getDriverClassName(), JdbcConnectionDetails::getDriverClassName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String get(String primary, Function<JdbcConnectionDetails, String> fallbackProperty) {
|
||||||
|
if (primary != null) {
|
||||||
|
return primary;
|
||||||
|
}
|
||||||
|
return (this.fallback != null) ? fallbackProperty.apply(this.fallback) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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.liquibase;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
|
||||||
|
import org.springframework.boot.jdbc.DatabaseDriver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Details required for Liquibase to establish a connection to an SQL service using JDBC.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
* @since 3.1.0
|
||||||
|
*/
|
||||||
|
public interface LiquibaseConnectionDetails extends ConnectionDetails {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Username for the database.
|
||||||
|
* @return the username for the database
|
||||||
|
*/
|
||||||
|
String getUsername();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password for the database.
|
||||||
|
* @return the password for the database
|
||||||
|
*/
|
||||||
|
String getPassword();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JDBC URL for the database.
|
||||||
|
* @return the JDBC URL for the database
|
||||||
|
*/
|
||||||
|
String getJdbcUrl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the JDBC driver class. Defaults to the class name of the driver
|
||||||
|
* specified in the JDBC URL.
|
||||||
|
* @return the JDBC driver class name
|
||||||
|
* @see #getJdbcUrl()
|
||||||
|
* @see DatabaseDriver#fromJdbcUrl(String)
|
||||||
|
* @see DatabaseDriver#getDriverClassName()
|
||||||
|
*/
|
||||||
|
default String getDriverClassName() {
|
||||||
|
return DatabaseDriver.fromJdbcUrl(getJdbcUrl()).getDriverClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -45,6 +45,12 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
@ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDatabaseFactory")
|
@ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDatabaseFactory")
|
||||||
public class MongoAutoConfiguration {
|
public class MongoAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(MongoConnectionDetails.class)
|
||||||
|
PropertiesMongoConnectionDetails mongoConnectionDetails(MongoProperties properties) {
|
||||||
|
return new PropertiesMongoConnectionDetails(properties);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(MongoClient.class)
|
@ConditionalOnMissingBean(MongoClient.class)
|
||||||
public MongoClient mongo(ObjectProvider<MongoClientSettingsBuilderCustomizer> builderCustomizers,
|
public MongoClient mongo(ObjectProvider<MongoClientSettingsBuilderCustomizer> builderCustomizers,
|
||||||
@ -63,9 +69,7 @@ public class MongoAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties,
|
StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties,
|
||||||
ObjectProvider<MongoConnectionDetails> connectionDetailsProvider) {
|
MongoConnectionDetails connectionDetails) {
|
||||||
MongoConnectionDetails connectionDetails = connectionDetailsProvider
|
|
||||||
.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties));
|
|
||||||
return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails.getConnectionString(),
|
return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails.getConnectionString(),
|
||||||
properties.getUuidRepresentation());
|
properties.getUuidRepresentation());
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,12 @@ import org.springframework.core.annotation.Order;
|
|||||||
@EnableConfigurationProperties(MongoProperties.class)
|
@EnableConfigurationProperties(MongoProperties.class)
|
||||||
public class MongoReactiveAutoConfiguration {
|
public class MongoReactiveAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(MongoConnectionDetails.class)
|
||||||
|
PropertiesMongoConnectionDetails mongoConnectionDetails(MongoProperties properties) {
|
||||||
|
return new PropertiesMongoConnectionDetails(properties);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public MongoClient reactiveStreamsMongoClient(
|
public MongoClient reactiveStreamsMongoClient(
|
||||||
@ -70,9 +76,7 @@ public class MongoReactiveAutoConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties,
|
StandardMongoClientSettingsBuilderCustomizer standardMongoSettingsCustomizer(MongoProperties properties,
|
||||||
ObjectProvider<MongoConnectionDetails> connectionDetailsProvider) {
|
MongoConnectionDetails connectionDetails) {
|
||||||
MongoConnectionDetails connectionDetails = connectionDetailsProvider
|
|
||||||
.getIfAvailable(() -> new PropertiesMongoConnectionDetails(properties));
|
|
||||||
return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails.getConnectionString(),
|
return new StandardMongoClientSettingsBuilderCustomizer(connectionDetails.getConnectionString(),
|
||||||
properties.getUuidRepresentation());
|
properties.getUuidRepresentation());
|
||||||
}
|
}
|
||||||
|
@ -61,13 +61,17 @@ import org.springframework.util.StringUtils;
|
|||||||
@EnableConfigurationProperties(Neo4jProperties.class)
|
@EnableConfigurationProperties(Neo4jProperties.class)
|
||||||
public class Neo4jAutoConfiguration {
|
public class Neo4jAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(Neo4jConnectionDetails.class)
|
||||||
|
PropertiesNeo4jConnectionDetails neo4jConnectionDetails(Neo4jProperties properties) {
|
||||||
|
return new PropertiesNeo4jConnectionDetails(properties);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public Driver neo4jDriver(Neo4jProperties properties, Environment environment,
|
public Driver neo4jDriver(Neo4jProperties properties, Environment environment,
|
||||||
ObjectProvider<ConfigBuilderCustomizer> configBuilderCustomizers,
|
Neo4jConnectionDetails connectionDetails,
|
||||||
ObjectProvider<Neo4jConnectionDetails> connectionDetailsProvider) {
|
ObjectProvider<ConfigBuilderCustomizer> configBuilderCustomizers) {
|
||||||
Neo4jConnectionDetails connectionDetails = connectionDetailsProvider
|
|
||||||
.getIfAvailable(() -> new PropertiesNeo4jConnectionDetails(properties));
|
|
||||||
AuthToken authToken = connectionDetails.getAuthToken();
|
AuthToken authToken = connectionDetails.getAuthToken();
|
||||||
Config config = mapDriverConfig(properties, connectionDetails,
|
Config config = mapDriverConfig(properties, connectionDetails,
|
||||||
configBuilderCustomizers.orderedStream().toList());
|
configBuilderCustomizers.orderedStream().toList());
|
||||||
|
@ -172,14 +172,21 @@ class RabbitAutoConfigurationTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesRabbitConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
void testConnectionFactoryWithOverridesWhenUsingConnectionDetails() {
|
void testConnectionFactoryWithOverridesWhenUsingCustomConnectionDetails() {
|
||||||
this.contextRunner.withUserConfiguration(TestConfiguration.class, ConnectionDetailsConfiguration.class)
|
this.contextRunner.withUserConfiguration(TestConfiguration.class, ConnectionDetailsConfiguration.class)
|
||||||
.withPropertyValues("spring.rabbitmq.host:remote-server", "spring.rabbitmq.port:9000",
|
.withPropertyValues("spring.rabbitmq.host:remote-server", "spring.rabbitmq.port:9000",
|
||||||
"spring.rabbitmq.username:alice", "spring.rabbitmq.password:secret",
|
"spring.rabbitmq.username:alice", "spring.rabbitmq.password:secret",
|
||||||
"spring.rabbitmq.virtual_host:/vhost")
|
"spring.rabbitmq.virtual_host:/vhost")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(RabbitConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesRabbitConnectionDetails.class);
|
||||||
CachingConnectionFactory connectionFactory = context.getBean(CachingConnectionFactory.class);
|
CachingConnectionFactory connectionFactory = context.getBean(CachingConnectionFactory.class);
|
||||||
assertThat(connectionFactory.getHost()).isEqualTo("rabbit.example.com");
|
assertThat(connectionFactory.getHost()).isEqualTo("rabbit.example.com");
|
||||||
assertThat(connectionFactory.getPort()).isEqualTo(12345);
|
assertThat(connectionFactory.getPort()).isEqualTo(12345);
|
||||||
|
@ -33,6 +33,7 @@ import com.datastax.oss.driver.internal.core.session.throttling.RateLimitingRequ
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration.PropertiesCassandraConnectionDetails;
|
||||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@ -95,13 +96,21 @@ class CassandraAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldUseConnectionDetails() {
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(PropertiesCassandraConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldUseCustomConnectionDetailsWhenDefined() {
|
||||||
this.contextRunner
|
this.contextRunner
|
||||||
.withPropertyValues("spring.cassandra.contact-points=localhost:9042", "spring.cassandra.username=a-user",
|
.withPropertyValues("spring.cassandra.contact-points=localhost:9042", "spring.cassandra.username=a-user",
|
||||||
"spring.cassandra.password=a-password", "spring.cassandra.local-datacenter=some-datacenter")
|
"spring.cassandra.password=a-password", "spring.cassandra.local-datacenter=some-datacenter")
|
||||||
.withBean(CassandraConnectionDetails.class, this::cassandraConnectionDetails)
|
.withBean(CassandraConnectionDetails.class, this::cassandraConnectionDetails)
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
assertThat(context).hasSingleBean(DriverConfigLoader.class);
|
assertThat(context).hasSingleBean(DriverConfigLoader.class)
|
||||||
|
.hasSingleBean(CassandraConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesCassandraConnectionDetails.class);
|
||||||
DriverExecutionProfile configuration = context.getBean(DriverConfigLoader.class)
|
DriverExecutionProfile configuration = context.getBean(DriverConfigLoader.class)
|
||||||
.getInitialConfig()
|
.getInitialConfig()
|
||||||
.getDefaultProfile();
|
.getDefaultProfile();
|
||||||
|
@ -34,6 +34,7 @@ import org.assertj.core.api.InstanceOfAssertFactories;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration.PropertiesCouchbaseConnectionDetails;
|
||||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -64,10 +65,20 @@ class CouchbaseAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldUseConnectionDetails() {
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner.withUserConfiguration(CouchbaseTestConfiguration.class)
|
||||||
|
.withPropertyValues("spring.couchbase.connection-string=localhost")
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(PropertiesCouchbaseConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldUseCustomConnectionDetailsWhenDefined() {
|
||||||
this.contextRunner.withBean(CouchbaseConnectionDetails.class, this::couchbaseConnectionDetails)
|
this.contextRunner.withBean(CouchbaseConnectionDetails.class, this::couchbaseConnectionDetails)
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
assertThat(context).hasSingleBean(ClusterEnvironment.class).hasSingleBean(Cluster.class);
|
assertThat(context).hasSingleBean(ClusterEnvironment.class)
|
||||||
|
.hasSingleBean(Cluster.class)
|
||||||
|
.hasSingleBean(CouchbaseConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesCouchbaseConnectionDetails.class);
|
||||||
Cluster cluster = context.getBean(Cluster.class);
|
Cluster cluster = context.getBean(Cluster.class);
|
||||||
assertThat(cluster.core()).extracting("connectionString.hosts")
|
assertThat(cluster.core()).extracting("connectionString.hosts")
|
||||||
.asList()
|
.asList()
|
||||||
|
@ -33,6 +33,7 @@ import org.springframework.boot.autoconfigure.data.mongo.country.Country;
|
|||||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
import org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails;
|
||||||
|
import org.springframework.boot.autoconfigure.mongo.PropertiesMongoConnectionDetails;
|
||||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -225,6 +226,25 @@ class MongoDataAutoConfigurationTests {
|
|||||||
.run((context) -> assertThat(context).hasSingleBean(MongoTemplate.class));
|
.run((context) -> assertThat(context).hasSingleBean(MongoTemplate.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesMongoConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldUseCustomConnectionDetailsWhenDefined() {
|
||||||
|
this.contextRunner.withBean(MongoConnectionDetails.class, () -> new MongoConnectionDetails() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConnectionString getConnectionString() {
|
||||||
|
return new ConnectionString("mongodb://localhost/testdb");
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(MongoConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesMongoConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
private static void assertDomainTypesDiscovered(MongoMappingContext mappingContext, Class<?>... types) {
|
private static void assertDomainTypesDiscovered(MongoMappingContext mappingContext, Class<?>... types) {
|
||||||
ManagedTypes managedTypes = (ManagedTypes) ReflectionTestUtils.getField(mappingContext, "managedTypes");
|
ManagedTypes managedTypes = (ManagedTypes) ReflectionTestUtils.getField(mappingContext, "managedTypes");
|
||||||
assertThat(managedTypes.toList()).containsOnly(types);
|
assertThat(managedTypes.toList()).containsOnly(types);
|
||||||
|
@ -495,8 +495,15 @@ class RedisAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void usesStandaloneFromConnectionDetailsIfAvailable() {
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesRedisConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void usesStandaloneFromCustomConnectionDetails() {
|
||||||
this.contextRunner.withUserConfiguration(ConnectionDetailsStandaloneConfiguration.class).run((context) -> {
|
this.contextRunner.withUserConfiguration(ConnectionDetailsStandaloneConfiguration.class).run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(RedisConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesRedisConnectionDetails.class);
|
||||||
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
|
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
|
||||||
assertThat(cf.isUseSsl()).isFalse();
|
assertThat(cf.isUseSsl()).isFalse();
|
||||||
RedisStandaloneConfiguration configuration = cf.getStandaloneConfiguration();
|
RedisStandaloneConfiguration configuration = cf.getStandaloneConfiguration();
|
||||||
@ -509,8 +516,10 @@ class RedisAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void usesSentinelFromConnectionDetailsIfAvailable() {
|
void usesSentinelFromCustomConnectionDetails() {
|
||||||
this.contextRunner.withUserConfiguration(ConnectionDetailsSentinelConfiguration.class).run((context) -> {
|
this.contextRunner.withUserConfiguration(ConnectionDetailsSentinelConfiguration.class).run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(RedisConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesRedisConnectionDetails.class);
|
||||||
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
|
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
|
||||||
assertThat(cf.isUseSsl()).isFalse();
|
assertThat(cf.isUseSsl()).isFalse();
|
||||||
RedisSentinelConfiguration configuration = cf.getSentinelConfiguration();
|
RedisSentinelConfiguration configuration = cf.getSentinelConfiguration();
|
||||||
@ -526,8 +535,10 @@ class RedisAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void usesClusterFromConnectionDetailsIfAvailable() {
|
void usesClusterFromCustomConnectionDetails() {
|
||||||
this.contextRunner.withUserConfiguration(ConnectionDetailsClusterConfiguration.class).run((context) -> {
|
this.contextRunner.withUserConfiguration(ConnectionDetailsClusterConfiguration.class).run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(RedisConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesRedisConnectionDetails.class);
|
||||||
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
|
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
|
||||||
assertThat(cf.isUseSsl()).isFalse();
|
assertThat(cf.isUseSsl()).isFalse();
|
||||||
RedisClusterConfiguration configuration = cf.getClusterConfiguration();
|
RedisClusterConfiguration configuration = cf.getClusterConfiguration();
|
||||||
|
@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node.Protocol;
|
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchConnectionDetails.Node.Protocol;
|
||||||
|
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.PropertiesElasticsearchConnectionDetails;
|
||||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -248,9 +249,17 @@ class ElasticsearchRestClientAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void connectionDetailsAreUsedIfAvailable() {
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(PropertiesElasticsearchConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldUseCustomConnectionDetailsWhenDefined() {
|
||||||
this.contextRunner.withUserConfiguration(ConnectionDetailsConfiguration.class).run((context) -> {
|
this.contextRunner.withUserConfiguration(ConnectionDetailsConfiguration.class).run((context) -> {
|
||||||
assertThat(context).hasSingleBean(RestClient.class);
|
assertThat(context).hasSingleBean(RestClient.class)
|
||||||
|
.hasSingleBean(ElasticsearchConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesElasticsearchConnectionDetails.class);
|
||||||
RestClient restClient = context.getBean(RestClient.class);
|
RestClient restClient = context.getBean(RestClient.class);
|
||||||
assertThat(restClient).hasFieldOrPropertyWithValue("pathPrefix", "/some-path");
|
assertThat(restClient).hasFieldOrPropertyWithValue("pathPrefix", "/some-path");
|
||||||
assertThat(restClient.getNodes().stream().map(Node::getHost).map(HttpHost::toString))
|
assertThat(restClient.getNodes().stream().map(Node::getHost).map(HttpHost::toString))
|
||||||
|
@ -40,6 +40,7 @@ import org.jooq.impl.DefaultDSLContext;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.InOrder;
|
import org.mockito.InOrder;
|
||||||
|
import org.postgresql.Driver;
|
||||||
|
|
||||||
import org.springframework.aot.hint.RuntimeHints;
|
import org.springframework.aot.hint.RuntimeHints;
|
||||||
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
||||||
@ -149,13 +150,34 @@ class FlywayAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createDataSourceWithJdbcConnectionDetails() {
|
void flywayPropertiesAreUsedOverJdbcConnectionDetails() {
|
||||||
this.contextRunner
|
this.contextRunner
|
||||||
.withUserConfiguration(EmbeddedDataSourceConfiguration.class, JdbcConnectionDetailsConfiguration.class,
|
.withUserConfiguration(EmbeddedDataSourceConfiguration.class, JdbcConnectionDetailsConfiguration.class,
|
||||||
MockFlywayMigrationStrategy.class)
|
MockFlywayMigrationStrategy.class)
|
||||||
.withPropertyValues("spring.flyway.url=jdbc:hsqldb:mem:flywaytest", "spring.flyway.user=some-user",
|
.withPropertyValues("spring.flyway.url=jdbc:hsqldb:mem:flywaytest", "spring.flyway.user=some-user",
|
||||||
"spring.flyway.password=some-password",
|
"spring.flyway.password=some-password",
|
||||||
"spring.flyway.driver-class-name=org.hsqldb.jdbc.JDBCDriver")
|
"spring.flyway.driver-class-name=org.hsqldb.jdbc.JDBCDriver")
|
||||||
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(Flyway.class);
|
||||||
|
Flyway flyway = context.getBean(Flyway.class);
|
||||||
|
DataSource dataSource = flyway.getConfiguration().getDataSource();
|
||||||
|
assertThat(dataSource).isInstanceOf(SimpleDriverDataSource.class);
|
||||||
|
SimpleDriverDataSource simpleDriverDataSource = (SimpleDriverDataSource) dataSource;
|
||||||
|
assertThat(simpleDriverDataSource.getUrl()).isEqualTo("jdbc:hsqldb:mem:flywaytest");
|
||||||
|
assertThat(simpleDriverDataSource.getUsername()).isEqualTo("some-user");
|
||||||
|
assertThat(simpleDriverDataSource.getPassword()).isEqualTo("some-password");
|
||||||
|
assertThat(simpleDriverDataSource.getDriver()).isInstanceOf(org.hsqldb.jdbc.JDBCDriver.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void flywayConnectionDetailsAreUsedOverFlywayProperties() {
|
||||||
|
this.contextRunner
|
||||||
|
.withUserConfiguration(EmbeddedDataSourceConfiguration.class, FlywayConnectionDetailsConfiguration.class,
|
||||||
|
MockFlywayMigrationStrategy.class)
|
||||||
|
.withPropertyValues("spring.flyway.url=jdbc:hsqldb:mem:flywaytest", "spring.flyway.user=some-user",
|
||||||
|
"spring.flyway.password=some-password",
|
||||||
|
"spring.flyway.driver-class-name=org.hsqldb.jdbc.JDBCDriver")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
assertThat(context).hasSingleBean(Flyway.class);
|
assertThat(context).hasSingleBean(Flyway.class);
|
||||||
Flyway flyway = context.getBean(Flyway.class);
|
Flyway flyway = context.getBean(Flyway.class);
|
||||||
@ -166,7 +188,7 @@ class FlywayAutoConfigurationTests {
|
|||||||
.isEqualTo("jdbc:postgresql://database.example.com:12345/database-1");
|
.isEqualTo("jdbc:postgresql://database.example.com:12345/database-1");
|
||||||
assertThat(simpleDriverDataSource.getUsername()).isEqualTo("user-1");
|
assertThat(simpleDriverDataSource.getUsername()).isEqualTo("user-1");
|
||||||
assertThat(simpleDriverDataSource.getPassword()).isEqualTo("secret-1");
|
assertThat(simpleDriverDataSource.getPassword()).isEqualTo("secret-1");
|
||||||
assertThat(simpleDriverDataSource.getDriver()).isInstanceOf(org.postgresql.Driver.class);
|
assertThat(simpleDriverDataSource.getDriver()).isInstanceOf(Driver.class);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,6 +268,19 @@ class FlywayAutoConfigurationTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void flywayDataSourceIsUsedWhenFlywayConnectionDetailsIsAvailable() {
|
||||||
|
this.contextRunner
|
||||||
|
.withUserConfiguration(FlywayDataSourceConfiguration.class, EmbeddedDataSourceConfiguration.class,
|
||||||
|
FlywayConnectionDetailsConfiguration.class)
|
||||||
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(FlywayConnectionDetails.class);
|
||||||
|
assertThat(context).hasSingleBean(Flyway.class);
|
||||||
|
assertThat(context.getBean(Flyway.class).getConfiguration().getDataSource())
|
||||||
|
.isEqualTo(context.getBean("flywayDataSource"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void flywayDataSourceWithoutDataSourceAutoConfiguration() {
|
void flywayDataSourceWithoutDataSourceAutoConfiguration() {
|
||||||
this.contextRunner.withUserConfiguration(FlywayDataSourceConfiguration.class).run((context) -> {
|
this.contextRunner.withUserConfiguration(FlywayDataSourceConfiguration.class).run((context) -> {
|
||||||
@ -1109,4 +1144,31 @@ class FlywayAutoConfigurationTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class FlywayConnectionDetailsConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
FlywayConnectionDetails flywayConnectionDetails() {
|
||||||
|
return new FlywayConnectionDetails() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJdbcUrl() {
|
||||||
|
return "jdbc:postgresql://database.example.com:12345/database-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return "user-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return "secret-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
import retrofit2.Retrofit;
|
import retrofit2.Retrofit;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration.PropertiesInfluxDbConnectionDetails;
|
||||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -54,9 +55,17 @@ class InfluxDbAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldUseConnectionDetails() {
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner.withPropertyValues("spring.influx.url=http://localhost")
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(PropertiesInfluxDbConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldUseCustomConnectionDetailsWhenDefined() {
|
||||||
this.contextRunner.withBean(InfluxDbConnectionDetails.class, this::influxDbConnectionDetails).run((context) -> {
|
this.contextRunner.withBean(InfluxDbConnectionDetails.class, this::influxDbConnectionDetails).run((context) -> {
|
||||||
assertThat(context).hasSingleBean(InfluxDB.class);
|
assertThat(context).hasSingleBean(InfluxDB.class)
|
||||||
|
.hasSingleBean(InfluxDbConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesInfluxDbConnectionDetails.class);
|
||||||
InfluxDB influxDb = context.getBean(InfluxDB.class);
|
InfluxDB influxDb = context.getBean(InfluxDB.class);
|
||||||
assertThat(influxDb).hasFieldOrPropertyWithValue("hostName", "localhost");
|
assertThat(influxDb).hasFieldOrPropertyWithValue("hostName", "localhost");
|
||||||
});
|
});
|
||||||
|
@ -249,13 +249,21 @@ class DataSourceAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void dbcp2UsesJdbcConnectionDetailsIfAvailable() {
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesJdbcConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void dbcp2UsesCustomConnectionDetailsWhenDefined() {
|
||||||
ApplicationContextRunner runner = new ApplicationContextRunner()
|
ApplicationContextRunner runner = new ApplicationContextRunner()
|
||||||
.withPropertyValues("spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource",
|
.withPropertyValues("spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource",
|
||||||
"spring.datasource.dbcp2.url=jdbc:broken", "spring.datasource.dbcp2.username=alice",
|
"spring.datasource.dbcp2.url=jdbc:broken", "spring.datasource.dbcp2.username=alice",
|
||||||
"spring.datasource.dbcp2.password=secret")
|
"spring.datasource.dbcp2.password=secret")
|
||||||
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class));
|
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
runner.withUserConfiguration(JdbcConnectionDetailsConfiguration.class).run((context) -> {
|
.withBean(JdbcConnectionDetails.class, TestJdbcConnectionDetails::new);
|
||||||
|
runner.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(JdbcConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesJdbcConnectionDetails.class);
|
||||||
DataSource dataSource = context.getBean(DataSource.class);
|
DataSource dataSource = context.getBean(DataSource.class);
|
||||||
assertThat(dataSource).asInstanceOf(InstanceOfAssertFactories.type(BasicDataSource.class))
|
assertThat(dataSource).asInstanceOf(InstanceOfAssertFactories.type(BasicDataSource.class))
|
||||||
.satisfies((dbcp2) -> {
|
.satisfies((dbcp2) -> {
|
||||||
@ -268,11 +276,14 @@ class DataSourceAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void genericUsesJdbcConnectionDetailsIfAvailable() {
|
void genericUsesCustomJdbcConnectionDetailsWhenAvailable() {
|
||||||
ApplicationContextRunner runner = new ApplicationContextRunner()
|
ApplicationContextRunner runner = new ApplicationContextRunner()
|
||||||
.withPropertyValues("spring.datasource.type=" + TestDataSource.class.getName())
|
.withPropertyValues("spring.datasource.type=" + TestDataSource.class.getName())
|
||||||
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class));
|
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
runner.withUserConfiguration(JdbcConnectionDetailsConfiguration.class).run((context) -> {
|
.withBean(JdbcConnectionDetails.class, TestJdbcConnectionDetails::new);
|
||||||
|
runner.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(JdbcConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesJdbcConnectionDetails.class);
|
||||||
DataSource dataSource = context.getBean(DataSource.class);
|
DataSource dataSource = context.getBean(DataSource.class);
|
||||||
assertThat(dataSource).isInstanceOf(TestDataSource.class);
|
assertThat(dataSource).isInstanceOf(TestDataSource.class);
|
||||||
TestDataSource source = (TestDataSource) dataSource;
|
TestDataSource source = (TestDataSource) dataSource;
|
||||||
|
@ -104,10 +104,12 @@ class HikariDataSourceConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void usesConnectionDetailsIfAvailable() {
|
void usesCustomConnectionDetailsWhenDefined() {
|
||||||
this.contextRunner.withUserConfiguration(ConnectionDetailsConfiguration.class)
|
this.contextRunner.withBean(JdbcConnectionDetails.class, TestJdbcConnectionDetails::new)
|
||||||
.withPropertyValues(PREFIX + "url=jdbc:broken", PREFIX + "username=alice", PREFIX + "password=secret")
|
.withPropertyValues(PREFIX + "url=jdbc:broken", PREFIX + "username=alice", PREFIX + "password=secret")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(JdbcConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesJdbcConnectionDetails.class);
|
||||||
DataSource dataSource = context.getBean(DataSource.class);
|
DataSource dataSource = context.getBean(DataSource.class);
|
||||||
assertThat(dataSource).asInstanceOf(InstanceOfAssertFactories.type(HikariDataSource.class))
|
assertThat(dataSource).asInstanceOf(InstanceOfAssertFactories.type(HikariDataSource.class))
|
||||||
.satisfies((hikari) -> {
|
.satisfies((hikari) -> {
|
||||||
|
@ -28,8 +28,6 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
import org.springframework.boot.jdbc.DatabaseDriver;
|
import org.springframework.boot.jdbc.DatabaseDriver;
|
||||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@ -114,10 +112,12 @@ class OracleUcpDataSourceConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void usesJdbcConnectionDetailsIfAvailable() {
|
void usesCustomJdbcConnectionDetailsWhenDefined() {
|
||||||
this.contextRunner.withUserConfiguration(ConnectionDetailsConfiguration.class)
|
this.contextRunner.withBean(JdbcConnectionDetails.class, TestJdbcConnectionDetails::new)
|
||||||
.withPropertyValues(PREFIX + "url=jdbc:broken", PREFIX + "username=alice", PREFIX + "password=secret")
|
.withPropertyValues(PREFIX + "url=jdbc:broken", PREFIX + "username=alice", PREFIX + "password=secret")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(JdbcConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesJdbcConnectionDetails.class);
|
||||||
DataSource dataSource = context.getBean(DataSource.class);
|
DataSource dataSource = context.getBean(DataSource.class);
|
||||||
assertThat(dataSource).isInstanceOf(PoolDataSourceImpl.class);
|
assertThat(dataSource).isInstanceOf(PoolDataSourceImpl.class);
|
||||||
PoolDataSourceImpl oracleUcp = (PoolDataSourceImpl) dataSource;
|
PoolDataSourceImpl oracleUcp = (PoolDataSourceImpl) dataSource;
|
||||||
@ -131,14 +131,4 @@ class OracleUcpDataSourceConfigurationTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
static class ConnectionDetailsConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
JdbcConnectionDetails jdbcConnectionDetails() {
|
|
||||||
return new TestJdbcConnectionDetails();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -117,10 +117,12 @@ class TomcatDataSourceConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void usesJdbcConnectionDetailsIfAvailable() {
|
void usesCustomJdbcConnectionDetailsWhenDefined() {
|
||||||
this.contextRunner.withUserConfiguration(ConnectionDetailsConfiguration.class)
|
this.contextRunner.withBean(JdbcConnectionDetails.class, TestJdbcConnectionDetails::new)
|
||||||
.withPropertyValues(PREFIX + "url=jdbc:broken", PREFIX + "username=alice", PREFIX + "password=secret")
|
.withPropertyValues(PREFIX + "url=jdbc:broken", PREFIX + "username=alice", PREFIX + "password=secret")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(JdbcConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesJdbcConnectionDetails.class);
|
||||||
DataSource dataSource = context.getBean(DataSource.class);
|
DataSource dataSource = context.getBean(DataSource.class);
|
||||||
assertThat(dataSource).isInstanceOf(org.apache.tomcat.jdbc.pool.DataSource.class);
|
assertThat(dataSource).isInstanceOf(org.apache.tomcat.jdbc.pool.DataSource.class);
|
||||||
org.apache.tomcat.jdbc.pool.DataSource tomcat = (org.apache.tomcat.jdbc.pool.DataSource) dataSource;
|
org.apache.tomcat.jdbc.pool.DataSource tomcat = (org.apache.tomcat.jdbc.pool.DataSource) dataSource;
|
||||||
@ -133,16 +135,6 @@ class TomcatDataSourceConfigurationTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
static class ConnectionDetailsConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
JdbcConnectionDetails jdbcConnectionDetails() {
|
|
||||||
return new TestJdbcConnectionDetails();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@EnableConfigurationProperties
|
@EnableConfigurationProperties
|
||||||
@EnableMBeanExport
|
@EnableMBeanExport
|
||||||
|
@ -96,7 +96,14 @@ class XADataSourceAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldUseConnectionDetailsIfAvailable() {
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(XADataSourceAutoConfiguration.class))
|
||||||
|
.withUserConfiguration(FromProperties.class)
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(PropertiesJdbcConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldUseCustomConnectionDetailsWhenDefined() {
|
||||||
JdbcConnectionDetails connectionDetails = mock(JdbcConnectionDetails.class);
|
JdbcConnectionDetails connectionDetails = mock(JdbcConnectionDetails.class);
|
||||||
given(connectionDetails.getUsername()).willReturn("user-1");
|
given(connectionDetails.getUsername()).willReturn("user-1");
|
||||||
given(connectionDetails.getPassword()).willReturn("password-1");
|
given(connectionDetails.getPassword()).willReturn("password-1");
|
||||||
@ -108,6 +115,8 @@ class XADataSourceAutoConfigurationTests {
|
|||||||
.withUserConfiguration(FromProperties.class)
|
.withUserConfiguration(FromProperties.class)
|
||||||
.withBean(JdbcConnectionDetails.class, () -> connectionDetails)
|
.withBean(JdbcConnectionDetails.class, () -> connectionDetails)
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(JdbcConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesJdbcConnectionDetails.class);
|
||||||
MockXADataSourceWrapper wrapper = context.getBean(MockXADataSourceWrapper.class);
|
MockXADataSourceWrapper wrapper = context.getBean(MockXADataSourceWrapper.class);
|
||||||
PGXADataSource dataSource = (PGXADataSource) wrapper.getXaDataSource();
|
PGXADataSource dataSource = (PGXADataSource) wrapper.getXaDataSource();
|
||||||
assertThat(dataSource).isNotNull();
|
assertThat(dataSource).isNotNull();
|
||||||
|
@ -164,6 +164,11 @@ class KafkaAutoConfigurationTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesKafkaConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void connectionDetailsAreAppliedToConsumer() {
|
void connectionDetailsAreAppliedToConsumer() {
|
||||||
this.contextRunner
|
this.contextRunner
|
||||||
@ -172,6 +177,8 @@ class KafkaAutoConfigurationTests {
|
|||||||
"spring.kafka.consumer.security.protocol=SSL")
|
"spring.kafka.consumer.security.protocol=SSL")
|
||||||
.withBean(KafkaConnectionDetails.class, this::kafkaConnectionDetails)
|
.withBean(KafkaConnectionDetails.class, this::kafkaConnectionDetails)
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(KafkaConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesKafkaConnectionDetails.class);
|
||||||
DefaultKafkaConsumerFactory<?, ?> consumerFactory = context.getBean(DefaultKafkaConsumerFactory.class);
|
DefaultKafkaConsumerFactory<?, ?> consumerFactory = context.getBean(DefaultKafkaConsumerFactory.class);
|
||||||
Map<String, Object> configs = consumerFactory.getConfigurationProperties();
|
Map<String, Object> configs = consumerFactory.getConfigurationProperties();
|
||||||
assertThat(configs).containsEntry(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG,
|
assertThat(configs).containsEntry(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG,
|
||||||
@ -240,6 +247,8 @@ class KafkaAutoConfigurationTests {
|
|||||||
"spring.kafka.producer.security.protocol=SSL")
|
"spring.kafka.producer.security.protocol=SSL")
|
||||||
.withBean(KafkaConnectionDetails.class, this::kafkaConnectionDetails)
|
.withBean(KafkaConnectionDetails.class, this::kafkaConnectionDetails)
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(KafkaConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesKafkaConnectionDetails.class);
|
||||||
DefaultKafkaProducerFactory<?, ?> producerFactory = context.getBean(DefaultKafkaProducerFactory.class);
|
DefaultKafkaProducerFactory<?, ?> producerFactory = context.getBean(DefaultKafkaProducerFactory.class);
|
||||||
Map<String, Object> configs = producerFactory.getConfigurationProperties();
|
Map<String, Object> configs = producerFactory.getConfigurationProperties();
|
||||||
assertThat(configs).containsEntry(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG,
|
assertThat(configs).containsEntry(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG,
|
||||||
@ -298,6 +307,8 @@ class KafkaAutoConfigurationTests {
|
|||||||
"spring.kafka.admin.security.protocol=SSL")
|
"spring.kafka.admin.security.protocol=SSL")
|
||||||
.withBean(KafkaConnectionDetails.class, this::kafkaConnectionDetails)
|
.withBean(KafkaConnectionDetails.class, this::kafkaConnectionDetails)
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(KafkaConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesKafkaConnectionDetails.class);
|
||||||
KafkaAdmin admin = context.getBean(KafkaAdmin.class);
|
KafkaAdmin admin = context.getBean(KafkaAdmin.class);
|
||||||
Map<String, Object> configs = admin.getConfigurationProperties();
|
Map<String, Object> configs = admin.getConfigurationProperties();
|
||||||
assertThat(configs).containsEntry(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG,
|
assertThat(configs).containsEntry(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG,
|
||||||
@ -363,6 +374,8 @@ class KafkaAutoConfigurationTests {
|
|||||||
"spring.kafka.security.protocol=SSL", "spring.kafka.streams.security.protocol=SSL")
|
"spring.kafka.security.protocol=SSL", "spring.kafka.streams.security.protocol=SSL")
|
||||||
.withBean(KafkaConnectionDetails.class, this::kafkaConnectionDetails)
|
.withBean(KafkaConnectionDetails.class, this::kafkaConnectionDetails)
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(KafkaConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesKafkaConnectionDetails.class);
|
||||||
Properties configs = context
|
Properties configs = context
|
||||||
.getBean(KafkaStreamsDefaultConfiguration.DEFAULT_STREAMS_CONFIG_BEAN_NAME,
|
.getBean(KafkaStreamsDefaultConfiguration.DEFAULT_STREAMS_CONFIG_BEAN_NAME,
|
||||||
KafkaStreamsConfiguration.class)
|
KafkaStreamsConfiguration.class)
|
||||||
|
@ -156,6 +156,49 @@ class LiquibaseAutoConfigurationTests {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void liquibaseDataSourceIsUsedOverLiquibaseConnectionDetails() {
|
||||||
|
this.contextRunner
|
||||||
|
.withUserConfiguration(LiquibaseDataSourceConfiguration.class,
|
||||||
|
LiquibaseConnectionDetailsConfiguration.class)
|
||||||
|
.run(assertLiquibase((liquibase) -> {
|
||||||
|
HikariDataSource dataSource = (HikariDataSource) liquibase.getDataSource();
|
||||||
|
assertThat(dataSource.getJdbcUrl()).startsWith("jdbc:hsqldb:mem:liquibasetest");
|
||||||
|
assertThat(dataSource.getUsername()).isEqualTo("sa");
|
||||||
|
assertThat(dataSource.getPassword()).isNull();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void liquibasePropertiesAreUsedOverJdbcConnectionDetails() {
|
||||||
|
this.contextRunner
|
||||||
|
.withPropertyValues("spring.liquibase.url=jdbc:hsqldb:mem:liquibasetest", "spring.liquibase.user=some-user",
|
||||||
|
"spring.liquibase.password=some-password",
|
||||||
|
"spring.liquibase.driver-class-name=org.hsqldb.jdbc.JDBCDriver")
|
||||||
|
.withUserConfiguration(JdbcConnectionDetailsConfiguration.class)
|
||||||
|
.run(assertLiquibase((liquibase) -> {
|
||||||
|
SimpleDriverDataSource dataSource = (SimpleDriverDataSource) liquibase.getDataSource();
|
||||||
|
assertThat(dataSource.getUrl()).startsWith("jdbc:hsqldb:mem:liquibasetest");
|
||||||
|
assertThat(dataSource.getUsername()).isEqualTo("some-user");
|
||||||
|
assertThat(dataSource.getPassword()).isEqualTo("some-password");
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void liquibaseConnectionDetailsAreUsedOverLiquibaseProperties() {
|
||||||
|
this.contextRunner.withSystemProperties("shouldRun=false")
|
||||||
|
.withPropertyValues("spring.liquibase.url=jdbc:hsqldb:mem:liquibasetest", "spring.liquibase.user=some-user",
|
||||||
|
"spring.liquibase.password=some-password",
|
||||||
|
"spring.liquibase.driver-class-name=org.hsqldb.jdbc.JDBCDriver")
|
||||||
|
.withUserConfiguration(LiquibaseConnectionDetailsConfiguration.class)
|
||||||
|
.run(assertLiquibase((liquibase) -> {
|
||||||
|
SimpleDriverDataSource dataSource = (SimpleDriverDataSource) liquibase.getDataSource();
|
||||||
|
assertThat(dataSource.getUrl()).isEqualTo("jdbc:postgresql://database.example.com:12345/database-1");
|
||||||
|
assertThat(dataSource.getUsername()).isEqualTo("user-1");
|
||||||
|
assertThat(dataSource.getPassword()).isEqualTo("secret-1");
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void changelogXml() {
|
void changelogXml() {
|
||||||
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
|
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
|
||||||
@ -578,6 +621,33 @@ class LiquibaseAutoConfigurationTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class LiquibaseConnectionDetailsConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
LiquibaseConnectionDetails liquibaseConnectionDetails() {
|
||||||
|
return new LiquibaseConnectionDetails() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJdbcUrl() {
|
||||||
|
return "jdbc:postgresql://database.example.com:12345/database-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return "user-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return "secret-1";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static class CustomH2Driver extends org.h2.Driver {
|
static class CustomH2Driver extends org.h2.Driver {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.mongo;
|
|||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import com.mongodb.ConnectionString;
|
||||||
import com.mongodb.MongoClientSettings;
|
import com.mongodb.MongoClientSettings;
|
||||||
import com.mongodb.client.MongoClient;
|
import com.mongodb.client.MongoClient;
|
||||||
import com.mongodb.client.MongoClients;
|
import com.mongodb.client.MongoClients;
|
||||||
@ -84,6 +85,25 @@ class MongoAutoConfigurationTests {
|
|||||||
.run((context) -> assertThat(getSettings(context).getApplicationName()).isEqualTo("overridden-name"));
|
.run((context) -> assertThat(getSettings(context).getApplicationName()).isEqualTo("overridden-name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesMongoConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldUseCustomConnectionDetailsWhenDefined() {
|
||||||
|
this.contextRunner.withBean(MongoConnectionDetails.class, () -> new MongoConnectionDetails() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConnectionString getConnectionString() {
|
||||||
|
return new ConnectionString("mongodb://localhost");
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(MongoConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesMongoConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
private MongoClientSettings getSettings(AssertableApplicationContext context) {
|
private MongoClientSettings getSettings(AssertableApplicationContext context) {
|
||||||
assertThat(context).hasSingleBean(MongoClient.class);
|
assertThat(context).hasSingleBean(MongoClient.class);
|
||||||
MongoClientImpl client = (MongoClientImpl) context.getBean(MongoClient.class);
|
MongoClientImpl client = (MongoClientImpl) context.getBean(MongoClient.class);
|
||||||
|
@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.mongo;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import com.mongodb.ConnectionString;
|
||||||
import com.mongodb.MongoClientSettings;
|
import com.mongodb.MongoClientSettings;
|
||||||
import com.mongodb.ReadPreference;
|
import com.mongodb.ReadPreference;
|
||||||
import com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory;
|
import com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory;
|
||||||
@ -111,6 +112,25 @@ class MongoReactiveAutoConfigurationTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesMongoConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldUseCustomConnectionDetailsWhenDefined() {
|
||||||
|
this.contextRunner.withBean(MongoConnectionDetails.class, () -> new MongoConnectionDetails() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConnectionString getConnectionString() {
|
||||||
|
return new ConnectionString("mongodb://localhost");
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(MongoConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesMongoConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
private MongoClientSettings getSettings(ApplicationContext context) {
|
private MongoClientSettings getSettings(ApplicationContext context) {
|
||||||
MongoClientImpl client = (MongoClientImpl) context.getBean(MongoClient.class);
|
MongoClientImpl client = (MongoClientImpl) context.getBean(MongoClient.class);
|
||||||
return client.getSettings();
|
return client.getSettings();
|
||||||
|
@ -105,8 +105,13 @@ class Neo4jAutoConfigurationTests {
|
|||||||
.hasMessageContaining("'%s' is not a supported scheme.", invalidScheme));
|
.hasMessageContaining("'%s' is not a supported scheme.", invalidScheme));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void definesPropertiesBasedConnectionDetailsByDefault() {
|
||||||
|
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesNeo4jConnectionDetails.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
void usesCustomConnectionDetails() {
|
void shouldUseCustomConnectionDetailsWhenDefined() {
|
||||||
this.contextRunner.withBean(Neo4jConnectionDetails.class, () -> new Neo4jConnectionDetails() {
|
this.contextRunner.withBean(Neo4jConnectionDetails.class, () -> new Neo4jConnectionDetails() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -115,7 +120,9 @@ class Neo4jAutoConfigurationTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}).run((context) -> {
|
}).run((context) -> {
|
||||||
assertThat(context).hasSingleBean(Driver.class);
|
assertThat(context).hasSingleBean(Driver.class)
|
||||||
|
.hasSingleBean(Neo4jConnectionDetails.class)
|
||||||
|
.doesNotHaveBean(PropertiesNeo4jConnectionDetails.class);
|
||||||
Driver driver = context.getBean(Driver.class);
|
Driver driver = context.getBean(Driver.class);
|
||||||
assertThat(driver.isEncrypted()).isTrue();
|
assertThat(driver.isEncrypted()).isTrue();
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* 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.test.autoconfigure.flyway;
|
||||||
|
|
||||||
|
import org.testcontainers.containers.JdbcDatabaseContainer;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.flyway.FlywayConnectionDetails;
|
||||||
|
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||||
|
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||||
|
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ContainerConnectionDetailsFactory} for
|
||||||
|
* {@link ServiceConnection @ServiceConnection}-annotated {@link JdbcDatabaseContainer}
|
||||||
|
* fields that should produce {@link FlywayConnectionDetails}.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
*/
|
||||||
|
class FlywayContainerConnectionDetailsFactory extends
|
||||||
|
ContainerConnectionDetailsFactory<ServiceConnection, FlywayConnectionDetails, JdbcDatabaseContainer<?>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FlywayConnectionDetails getContainerConnectionDetails(
|
||||||
|
ContainerConnectionSource<ServiceConnection, FlywayConnectionDetails, JdbcDatabaseContainer<?>> source) {
|
||||||
|
return new FlywayContainerConnectionDetails(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link FlywayConnectionDetails} backed by a {@link JdbcDatabaseContainer}.
|
||||||
|
*/
|
||||||
|
private static final class FlywayContainerConnectionDetails extends ContainerConnectionDetails
|
||||||
|
implements FlywayConnectionDetails {
|
||||||
|
|
||||||
|
private final JdbcDatabaseContainer<?> container;
|
||||||
|
|
||||||
|
private FlywayContainerConnectionDetails(
|
||||||
|
ContainerConnectionSource<ServiceConnection, FlywayConnectionDetails, JdbcDatabaseContainer<?>> source) {
|
||||||
|
super(source);
|
||||||
|
this.container = source.getContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return this.container.getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return this.container.getPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJdbcUrl() {
|
||||||
|
return this.container.getJdbcUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDriverClassName() {
|
||||||
|
return this.container.getDriverClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-configuration for using Flyway in tests.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.test.autoconfigure.flyway;
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* 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.test.autoconfigure.liquibase;
|
||||||
|
|
||||||
|
import org.testcontainers.containers.JdbcDatabaseContainer;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.liquibase.LiquibaseConnectionDetails;
|
||||||
|
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionDetailsFactory;
|
||||||
|
import org.springframework.boot.test.autoconfigure.service.connection.ContainerConnectionSource;
|
||||||
|
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ContainerConnectionDetailsFactory} for
|
||||||
|
* {@link ServiceConnection @ServiceConnection}-annotated {@link JdbcDatabaseContainer}
|
||||||
|
* fields that should produce {@link LiquibaseConnectionDetails}.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
*/
|
||||||
|
class LiquibaseContainerConnectionDetailsFactory extends
|
||||||
|
ContainerConnectionDetailsFactory<ServiceConnection, LiquibaseConnectionDetails, JdbcDatabaseContainer<?>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LiquibaseConnectionDetails getContainerConnectionDetails(
|
||||||
|
ContainerConnectionSource<ServiceConnection, LiquibaseConnectionDetails, JdbcDatabaseContainer<?>> source) {
|
||||||
|
return new LiquibaseContainerConnectionDetails(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link LiquibaseConnectionDetails} backed by a {@link JdbcDatabaseContainer}.
|
||||||
|
*/
|
||||||
|
private static final class LiquibaseContainerConnectionDetails extends ContainerConnectionDetails
|
||||||
|
implements LiquibaseConnectionDetails {
|
||||||
|
|
||||||
|
private final JdbcDatabaseContainer<?> container;
|
||||||
|
|
||||||
|
private LiquibaseContainerConnectionDetails(
|
||||||
|
ContainerConnectionSource<ServiceConnection, LiquibaseConnectionDetails, JdbcDatabaseContainer<?>> source) {
|
||||||
|
super(source);
|
||||||
|
this.container = source.getContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return this.container.getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return this.container.getPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getJdbcUrl() {
|
||||||
|
return this.container.getJdbcUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDriverClassName() {
|
||||||
|
return this.container.getDriverClassName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-configuration for using Liquibase in tests.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.test.autoconfigure.liquibase;
|
@ -26,9 +26,11 @@ org.springframework.boot.test.autoconfigure.cassandra.CassandraContainerConnecti
|
|||||||
org.springframework.boot.test.autoconfigure.couchbase.CouchbaseContainerConnectionDetailsFactory,\
|
org.springframework.boot.test.autoconfigure.couchbase.CouchbaseContainerConnectionDetailsFactory,\
|
||||||
org.springframework.boot.test.autoconfigure.data.redis.RedisContainerConnectionDetailsFactory,\
|
org.springframework.boot.test.autoconfigure.data.redis.RedisContainerConnectionDetailsFactory,\
|
||||||
org.springframework.boot.test.autoconfigure.elasticsearch.ElasticsearchContainerConnectionDetailsFactory,\
|
org.springframework.boot.test.autoconfigure.elasticsearch.ElasticsearchContainerConnectionDetailsFactory,\
|
||||||
|
org.springframework.boot.test.autoconfigure.flyway.FlywayContainerConnectionDetailsFactory,\
|
||||||
org.springframework.boot.test.autoconfigure.influx.InfluxDbContainerConnectionDetailsFactory,\
|
org.springframework.boot.test.autoconfigure.influx.InfluxDbContainerConnectionDetailsFactory,\
|
||||||
org.springframework.boot.test.autoconfigure.jdbc.JdbcContainerConnectionDetailsFactory,\
|
org.springframework.boot.test.autoconfigure.jdbc.JdbcContainerConnectionDetailsFactory,\
|
||||||
org.springframework.boot.test.autoconfigure.kafka.KafkaContainerConnectionDetailsFactory,\
|
org.springframework.boot.test.autoconfigure.kafka.KafkaContainerConnectionDetailsFactory,\
|
||||||
|
org.springframework.boot.test.autoconfigure.liquibase.LiquibaseContainerConnectionDetailsFactory,\
|
||||||
org.springframework.boot.test.autoconfigure.mongo.MongoContainerConnectionDetailsFactory,\
|
org.springframework.boot.test.autoconfigure.mongo.MongoContainerConnectionDetailsFactory,\
|
||||||
org.springframework.boot.test.autoconfigure.neo4j.Neo4jContainerConnectionDetailsFactory,\
|
org.springframework.boot.test.autoconfigure.neo4j.Neo4jContainerConnectionDetailsFactory,\
|
||||||
org.springframework.boot.test.autoconfigure.r2dbc.MariaDbR2dbcContainerConnectionDetailsFactory,\
|
org.springframework.boot.test.autoconfigure.r2dbc.MariaDbR2dbcContainerConnectionDetailsFactory,\
|
||||||
|
@ -23,9 +23,10 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.flyway.FlywayConnectionDetails;
|
||||||
import org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest;
|
import org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest;
|
||||||
import org.springframework.boot.test.autoconfigure.jdbc.JdbcServiceConnection;
|
|
||||||
import org.springframework.boot.test.autoconfigure.r2dbc.R2dbcServiceConnection;
|
import org.springframework.boot.test.autoconfigure.r2dbc.R2dbcServiceConnection;
|
||||||
|
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||||
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
|
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@ -42,8 +43,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
class CityRepositoryTests {
|
class CityRepositoryTests {
|
||||||
|
|
||||||
@Container
|
@Container
|
||||||
@JdbcServiceConnection
|
|
||||||
@R2dbcServiceConnection
|
@R2dbcServiceConnection
|
||||||
|
@ServiceConnection(FlywayConnectionDetails.class)
|
||||||
static PostgreSQLContainer<?> postgresql = new PostgreSQLContainer<>(DockerImageNames.postgresql())
|
static PostgreSQLContainer<?> postgresql = new PostgreSQLContainer<>(DockerImageNames.postgresql())
|
||||||
.withDatabaseName("test_flyway");
|
.withDatabaseName("test_flyway");
|
||||||
|
|
||||||
|
@ -23,9 +23,10 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.liquibase.LiquibaseConnectionDetails;
|
||||||
import org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest;
|
import org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest;
|
||||||
import org.springframework.boot.test.autoconfigure.jdbc.JdbcServiceConnection;
|
|
||||||
import org.springframework.boot.test.autoconfigure.r2dbc.R2dbcServiceConnection;
|
import org.springframework.boot.test.autoconfigure.r2dbc.R2dbcServiceConnection;
|
||||||
|
import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnection;
|
||||||
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
|
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@ -42,8 +43,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
class CityRepositoryTests {
|
class CityRepositoryTests {
|
||||||
|
|
||||||
@Container
|
@Container
|
||||||
@JdbcServiceConnection
|
|
||||||
@R2dbcServiceConnection
|
@R2dbcServiceConnection
|
||||||
|
@ServiceConnection(LiquibaseConnectionDetails.class)
|
||||||
static PostgreSQLContainer<?> postgresql = new PostgreSQLContainer<>(DockerImageNames.postgresql())
|
static PostgreSQLContainer<?> postgresql = new PostgreSQLContainer<>(DockerImageNames.postgresql())
|
||||||
.withDatabaseName("test_liquibase");
|
.withDatabaseName("test_liquibase");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user