Use driver class name from JdbcConnectionDetails

Fixes gh-34777
This commit is contained in:
Andy Wilkinson 2023-03-27 11:39:28 +01:00
parent b91f814e42
commit d69335d94a
11 changed files with 49 additions and 26 deletions

View File

@ -49,17 +49,18 @@ import org.springframework.util.StringUtils;
abstract class DataSourceConfiguration { abstract class DataSourceConfiguration {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected static <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) { private static <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) {
return (T) properties.initializeDataSourceBuilder().type(type).build(); return (T) properties.initializeDataSourceBuilder().type(type).build();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected 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)
.url(connectionDetails.getJdbcUrl()) .url(connectionDetails.getJdbcUrl())
.username(connectionDetails.getUsername()) .username(connectionDetails.getUsername())
.password(connectionDetails.getPassword()) .password(connectionDetails.getPassword())
.driverClassName(connectionDetails.getDriverClassName())
.type(type) .type(type)
.build(); .build();
} }
@ -213,12 +214,7 @@ abstract class DataSourceConfiguration {
ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) { ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
JdbcConnectionDetails connectionDetails = connectionDetailsProvider.getIfAvailable(); JdbcConnectionDetails connectionDetails = connectionDetailsProvider.getIfAvailable();
if (connectionDetails != null) { if (connectionDetails != null) {
return DataSourceBuilder.create(properties.getClassLoader()) return createDataSource(connectionDetails, properties.getType(), properties.getClassLoader());
.url(connectionDetails.getJdbcUrl())
.username(connectionDetails.getUsername())
.password(connectionDetails.getPassword())
.type(properties.getType())
.build();
} }
return properties.initializeDataSourceBuilder().build(); return properties.initializeDataSourceBuilder().build();
} }

View File

@ -261,8 +261,8 @@ class DataSourceAutoConfigurationTests {
.satisfies((dbcp2) -> { .satisfies((dbcp2) -> {
assertThat(dbcp2.getUsername()).isEqualTo("user-1"); assertThat(dbcp2.getUsername()).isEqualTo("user-1");
assertThat(dbcp2.getPassword()).isEqualTo("password-1"); assertThat(dbcp2.getPassword()).isEqualTo("password-1");
assertThat(dbcp2.getDriverClassName()).isEqualTo("org.postgresql.Driver"); assertThat(dbcp2.getDriverClassName()).isEqualTo(DatabaseDriver.POSTGRESQL.getDriverClassName());
assertThat(dbcp2.getUrl()).isEqualTo("jdbc:postgresql://postgres.example.com:12345/database-1"); assertThat(dbcp2.getUrl()).isEqualTo("jdbc:customdb://customdb.example.com:12345/database-1");
}); });
}); });
} }
@ -278,8 +278,9 @@ class DataSourceAutoConfigurationTests {
TestDataSource source = (TestDataSource) dataSource; TestDataSource source = (TestDataSource) dataSource;
assertThat(source.getUsername()).isEqualTo("user-1"); assertThat(source.getUsername()).isEqualTo("user-1");
assertThat(source.getPassword()).isEqualTo("password-1"); assertThat(source.getPassword()).isEqualTo("password-1");
assertThat(source.getDriver().getClass().getName()).isEqualTo("org.postgresql.Driver"); assertThat(source.getDriver().getClass().getName())
assertThat(source.getUrl()).isEqualTo("jdbc:postgresql://postgres.example.com:12345/database-1"); .isEqualTo(DatabaseDriver.POSTGRESQL.getDriverClassName());
assertThat(source.getUrl()).isEqualTo("jdbc:customdb://customdb.example.com:12345/database-1");
}); });
} }

View File

@ -33,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class Dbcp2JdbcConnectionDetailsBeanPostProcessorTests { class Dbcp2JdbcConnectionDetailsBeanPostProcessorTests {
@Test @Test
void setUsernamePasswordAndUrl() { void setUsernamePasswordUrlAndDriverClassName() {
BasicDataSource dataSource = new BasicDataSource(); BasicDataSource dataSource = new BasicDataSource();
dataSource.setUrl("will-be-overwritten"); dataSource.setUrl("will-be-overwritten");
dataSource.setUsername("will-be-overwritten"); dataSource.setUsername("will-be-overwritten");
@ -41,7 +41,7 @@ class Dbcp2JdbcConnectionDetailsBeanPostProcessorTests {
dataSource.setDriverClassName("will-be-overwritten"); dataSource.setDriverClassName("will-be-overwritten");
new Dbcp2JdbcConnectionDetailsBeanPostProcessor(null).processDataSource(dataSource, new Dbcp2JdbcConnectionDetailsBeanPostProcessor(null).processDataSource(dataSource,
new TestJdbcConnectionDetails()); new TestJdbcConnectionDetails());
assertThat(dataSource.getUrl()).isEqualTo("jdbc:postgresql://postgres.example.com:12345/database-1"); assertThat(dataSource.getUrl()).isEqualTo("jdbc:customdb://customdb.example.com:12345/database-1");
assertThat(dataSource.getUsername()).isEqualTo("user-1"); assertThat(dataSource.getUsername()).isEqualTo("user-1");
assertThat(dataSource.getPassword()).isEqualTo("password-1"); assertThat(dataSource.getPassword()).isEqualTo("password-1");
assertThat(dataSource.getDriverClassName()).isEqualTo(DatabaseDriver.POSTGRESQL.getDriverClassName()); assertThat(dataSource.getDriverClassName()).isEqualTo(DatabaseDriver.POSTGRESQL.getDriverClassName());

View File

@ -115,7 +115,7 @@ class HikariDataSourceConfigurationTests {
assertThat(hikari.getPassword()).isEqualTo("password-1"); assertThat(hikari.getPassword()).isEqualTo("password-1");
assertThat(hikari.getDriverClassName()).isEqualTo("org.postgresql.Driver"); assertThat(hikari.getDriverClassName()).isEqualTo("org.postgresql.Driver");
assertThat(hikari.getJdbcUrl()) assertThat(hikari.getJdbcUrl())
.isEqualTo("jdbc:postgresql://postgres.example.com:12345/database-1"); .isEqualTo("jdbc:customdb://customdb.example.com:12345/database-1");
}); });
}); });
} }

View File

@ -41,7 +41,7 @@ class HikariJdbcConnectionDetailsBeanPostProcessorTests {
dataSource.setDriverClassName(DatabaseDriver.H2.getDriverClassName()); dataSource.setDriverClassName(DatabaseDriver.H2.getDriverClassName());
new HikariJdbcConnectionDetailsBeanPostProcessor(null).processDataSource(dataSource, new HikariJdbcConnectionDetailsBeanPostProcessor(null).processDataSource(dataSource,
new TestJdbcConnectionDetails()); new TestJdbcConnectionDetails());
assertThat(dataSource.getJdbcUrl()).isEqualTo("jdbc:postgresql://postgres.example.com:12345/database-1"); assertThat(dataSource.getJdbcUrl()).isEqualTo("jdbc:customdb://customdb.example.com:12345/database-1");
assertThat(dataSource.getUsername()).isEqualTo("user-1"); assertThat(dataSource.getUsername()).isEqualTo("user-1");
assertThat(dataSource.getPassword()).isEqualTo("password-1"); assertThat(dataSource.getPassword()).isEqualTo("password-1");
assertThat(dataSource.getDriverClassName()).isEqualTo(DatabaseDriver.POSTGRESQL.getDriverClassName()); assertThat(dataSource.getDriverClassName()).isEqualTo(DatabaseDriver.POSTGRESQL.getDriverClassName());

View File

@ -26,6 +26,7 @@ import oracle.ucp.util.OpaqueString;
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.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.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -124,8 +125,9 @@ class OracleUcpDataSourceConfigurationTests {
assertThat(oracleUcp).extracting("password") assertThat(oracleUcp).extracting("password")
.extracting((o) -> ((OpaqueString) o).get()) .extracting((o) -> ((OpaqueString) o).get())
.isEqualTo("password-1"); .isEqualTo("password-1");
assertThat(oracleUcp.getConnectionFactoryClassName()).isEqualTo("org.postgresql.Driver"); assertThat(oracleUcp.getConnectionFactoryClassName())
assertThat(oracleUcp.getURL()).isEqualTo("jdbc:postgresql://postgres.example.com:12345/database-1"); .isEqualTo(DatabaseDriver.POSTGRESQL.getDriverClassName());
assertThat(oracleUcp.getURL()).isEqualTo("jdbc:customdb://customdb.example.com:12345/database-1");
}); });
} }

View File

@ -36,7 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class OracleUcpJdbcConnectionDetailsBeanPostProcessorTests { class OracleUcpJdbcConnectionDetailsBeanPostProcessorTests {
@Test @Test
void setUsernamePasswordAndUrl() throws SQLException { void setUsernamePasswordUrlAndDriverClassName() throws SQLException {
PoolDataSourceImpl dataSource = new PoolDataSourceImpl(); PoolDataSourceImpl dataSource = new PoolDataSourceImpl();
dataSource.setURL("will-be-overwritten"); dataSource.setURL("will-be-overwritten");
dataSource.setUser("will-be-overwritten"); dataSource.setUser("will-be-overwritten");
@ -44,7 +44,7 @@ class OracleUcpJdbcConnectionDetailsBeanPostProcessorTests {
dataSource.setConnectionFactoryClassName("will-be-overwritten"); dataSource.setConnectionFactoryClassName("will-be-overwritten");
new OracleUcpJdbcConnectionDetailsBeanPostProcessor(null).processDataSource(dataSource, new OracleUcpJdbcConnectionDetailsBeanPostProcessor(null).processDataSource(dataSource,
new TestJdbcConnectionDetails()); new TestJdbcConnectionDetails());
assertThat(dataSource.getURL()).isEqualTo("jdbc:postgresql://postgres.example.com:12345/database-1"); assertThat(dataSource.getURL()).isEqualTo("jdbc:customdb://customdb.example.com:12345/database-1");
assertThat(dataSource.getUser()).isEqualTo("user-1"); assertThat(dataSource.getUser()).isEqualTo("user-1");
assertThat(dataSource).extracting("password") assertThat(dataSource).extracting("password")
.extracting((password) -> ((OpaqueString) password).get()) .extracting((password) -> ((OpaqueString) password).get())

View File

@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.jdbc; package org.springframework.boot.autoconfigure.jdbc;
import org.springframework.boot.jdbc.DatabaseDriver;
/** /**
* {@link JdbcConnectionDetails} used in tests. * {@link JdbcConnectionDetails} used in tests.
* *
@ -25,7 +27,7 @@ class TestJdbcConnectionDetails implements JdbcConnectionDetails {
@Override @Override
public String getJdbcUrl() { public String getJdbcUrl() {
return "jdbc:postgresql://postgres.example.com:12345/database-1"; return "jdbc:customdb://customdb.example.com:12345/database-1";
} }
@Override @Override
@ -38,4 +40,14 @@ class TestJdbcConnectionDetails implements JdbcConnectionDetails {
return "password-1"; return "password-1";
} }
@Override
public String getDriverClassName() {
return DatabaseDriver.POSTGRESQL.getDriverClassName();
}
@Override
public String getXaDataSourceClassName() {
return DatabaseDriver.POSTGRESQL.getXaDataSourceClassName();
}
} }

View File

@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
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.DatabaseDriver;
import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@ -125,9 +126,10 @@ class TomcatDataSourceConfigurationTests {
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;
assertThat(tomcat.getPoolProperties().getUsername()).isEqualTo("user-1"); assertThat(tomcat.getPoolProperties().getUsername()).isEqualTo("user-1");
assertThat(tomcat.getPoolProperties().getPassword()).isEqualTo("password-1"); assertThat(tomcat.getPoolProperties().getPassword()).isEqualTo("password-1");
assertThat(tomcat.getPoolProperties().getDriverClassName()).isEqualTo("org.postgresql.Driver"); assertThat(tomcat.getPoolProperties().getDriverClassName())
.isEqualTo(DatabaseDriver.POSTGRESQL.getDriverClassName());
assertThat(tomcat.getPoolProperties().getUrl()) assertThat(tomcat.getPoolProperties().getUrl())
.isEqualTo("jdbc:postgresql://postgres.example.com:12345/database-1"); .isEqualTo("jdbc:customdb://customdb.example.com:12345/database-1");
}); });
} }

View File

@ -33,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class TomcatJdbcConnectionDetailsBeanPostProcessorTests { class TomcatJdbcConnectionDetailsBeanPostProcessorTests {
@Test @Test
void setUsernamePasswordAndUrl() { void setUsernamePasswordUrlAndDriverClassName() {
DataSource dataSource = new DataSource(); DataSource dataSource = new DataSource();
dataSource.setUrl("will-be-overwritten"); dataSource.setUrl("will-be-overwritten");
dataSource.setUsername("will-be-overwritten"); dataSource.setUsername("will-be-overwritten");
@ -41,7 +41,7 @@ class TomcatJdbcConnectionDetailsBeanPostProcessorTests {
dataSource.setDriverClassName("will-be-overwritten"); dataSource.setDriverClassName("will-be-overwritten");
new TomcatJdbcConnectionDetailsBeanPostProcessor(null).processDataSource(dataSource, new TomcatJdbcConnectionDetailsBeanPostProcessor(null).processDataSource(dataSource,
new TestJdbcConnectionDetails()); new TestJdbcConnectionDetails());
assertThat(dataSource.getUrl()).isEqualTo("jdbc:postgresql://postgres.example.com:12345/database-1"); assertThat(dataSource.getUrl()).isEqualTo("jdbc:customdb://customdb.example.com:12345/database-1");
assertThat(dataSource.getUsername()).isEqualTo("user-1"); assertThat(dataSource.getUsername()).isEqualTo("user-1");
assertThat(dataSource.getPoolProperties().getPassword()).isEqualTo("password-1"); assertThat(dataSource.getPoolProperties().getPassword()).isEqualTo("password-1");
assertThat(dataSource.getPoolProperties().getDriverClassName()) assertThat(dataSource.getPoolProperties().getDriverClassName())

View File

@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test;
import org.postgresql.xa.PGXADataSource; import org.postgresql.xa.PGXADataSource;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.jdbc.XADataSourceWrapper; import org.springframework.boot.jdbc.XADataSourceWrapper;
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;
@ -35,6 +36,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
/** /**
@ -95,8 +97,16 @@ class XADataSourceAutoConfigurationTests {
@Test @Test
void shouldUseConnectionDetailsIfAvailable() { void shouldUseConnectionDetailsIfAvailable() {
JdbcConnectionDetails connectionDetails = mock(JdbcConnectionDetails.class);
given(connectionDetails.getUsername()).willReturn("user-1");
given(connectionDetails.getPassword()).willReturn("password-1");
given(connectionDetails.getJdbcUrl()).willReturn("jdbc:postgresql://postgres.example.com:12345/database-1");
given(connectionDetails.getDriverClassName()).willReturn(DatabaseDriver.POSTGRESQL.getDriverClassName());
given(connectionDetails.getXaDataSourceClassName())
.willReturn(DatabaseDriver.POSTGRESQL.getXaDataSourceClassName());
new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(XADataSourceAutoConfiguration.class)) new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(XADataSourceAutoConfiguration.class))
.withUserConfiguration(FromProperties.class, JdbcConnectionDetailsConfiguration.class) .withUserConfiguration(FromProperties.class)
.withBean(JdbcConnectionDetails.class, () -> connectionDetails)
.run((context) -> { .run((context) -> {
MockXADataSourceWrapper wrapper = context.getBean(MockXADataSourceWrapper.class); MockXADataSourceWrapper wrapper = context.getBean(MockXADataSourceWrapper.class);
PGXADataSource dataSource = (PGXADataSource) wrapper.getXaDataSource(); PGXADataSource dataSource = (PGXADataSource) wrapper.getXaDataSource();