Commit ee7a686e authored by Andy Wilkinson's avatar Andy Wilkinson

Merge pull request #23958 from evgeniycheban

* gh-23958:
  Polish "Add liquibase driver class name property"
  Add liquibase driver class name property

Closes gh-23958
parents 97fbef60 2db8e7ee
...@@ -44,6 +44,7 @@ import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfigurati ...@@ -44,6 +44,7 @@ import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfigurati
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
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.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -53,6 +54,7 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; ...@@ -53,6 +54,7 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.datasource.SimpleDriverDataSource; import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.util.StringUtils;
/** /**
* {@link EnableAutoConfiguration Auto-configuration} for Liquibase. * {@link EnableAutoConfiguration Auto-configuration} for Liquibase.
...@@ -66,6 +68,7 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; ...@@ -66,6 +68,7 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
* @author Dan Zheng * @author Dan Zheng
* @author András Deák * @author András Deák
* @author Ferenc Gratzer * @author Ferenc Gratzer
* @author Evgeniy Cheban
* @since 1.1.0 * @since 1.1.0
*/ */
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
...@@ -146,8 +149,19 @@ public class LiquibaseAutoConfiguration { ...@@ -146,8 +149,19 @@ public class LiquibaseAutoConfiguration {
String url = getProperty(this.properties::getUrl, dataSourceProperties::determineUrl); String url = getProperty(this.properties::getUrl, dataSourceProperties::determineUrl);
String user = getProperty(this.properties::getUser, dataSourceProperties::determineUsername); String user = getProperty(this.properties::getUser, dataSourceProperties::determineUsername);
String password = getProperty(this.properties::getPassword, dataSourceProperties::determinePassword); String password = getProperty(this.properties::getPassword, dataSourceProperties::determinePassword);
String driverClassName = determineDriverClassName(dataSourceProperties, url);
return DataSourceBuilder.create().type(determineDataSourceType()).url(url).username(user).password(password) return DataSourceBuilder.create().type(determineDataSourceType()).url(url).username(user).password(password)
.build(); .driverClassName(driverClassName).build();
}
private String determineDriverClassName(DataSourceProperties dataSourceProperties, String url) {
if (StringUtils.hasText(this.properties.getDriverClassName())) {
return this.properties.getDriverClassName();
}
if (StringUtils.hasText(dataSourceProperties.getDriverClassName())) {
return dataSourceProperties.getDriverClassName();
}
return StringUtils.hasText(url) ? DatabaseDriver.fromJdbcUrl(url).getDriverClassName() : null;
} }
private Class<? extends DataSource> determineDataSourceType() { private Class<? extends DataSource> determineDataSourceType() {
......
...@@ -30,6 +30,7 @@ import org.springframework.util.Assert; ...@@ -30,6 +30,7 @@ import org.springframework.util.Assert;
* @author Marcel Overdijk * @author Marcel Overdijk
* @author Eddú Meléndez * @author Eddú Meléndez
* @author Ferenc Gratzer * @author Ferenc Gratzer
* @author Evgeniy Cheban
* @since 1.1.0 * @since 1.1.0
*/ */
@ConfigurationProperties(prefix = "spring.liquibase", ignoreUnknownFields = false) @ConfigurationProperties(prefix = "spring.liquibase", ignoreUnknownFields = false)
...@@ -96,6 +97,11 @@ public class LiquibaseProperties { ...@@ -96,6 +97,11 @@ public class LiquibaseProperties {
*/ */
private String password; private String password;
/**
* Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
*/
private String driverClassName;
/** /**
* JDBC URL of the database to migrate. If not set, the primary configured data source * JDBC URL of the database to migrate. If not set, the primary configured data source
* is used. * is used.
...@@ -226,6 +232,14 @@ public class LiquibaseProperties { ...@@ -226,6 +232,14 @@ public class LiquibaseProperties {
this.password = password; this.password = password;
} }
public String getDriverClassName() {
return this.driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() { public String getUrl() {
return this.url; return this.url;
} }
......
...@@ -73,6 +73,7 @@ import static org.assertj.core.api.Assertions.contentOf; ...@@ -73,6 +73,7 @@ import static org.assertj.core.api.Assertions.contentOf;
* @author András Deák * @author András Deák
* @author Andrii Hrytsiuk * @author Andrii Hrytsiuk
* @author Ferenc Gratzer * @author Ferenc Gratzer
* @author Evgeniy Cheban
*/ */
@ExtendWith(OutputCaptureExtension.class) @ExtendWith(OutputCaptureExtension.class)
class LiquibaseAutoConfigurationTests { class LiquibaseAutoConfigurationTests {
...@@ -222,6 +223,38 @@ class LiquibaseAutoConfigurationTests { ...@@ -222,6 +223,38 @@ class LiquibaseAutoConfigurationTests {
DataSource dataSource = liquibase.getDataSource(); DataSource dataSource = liquibase.getDataSource();
assertThat(((HikariDataSource) dataSource).isClosed()).isTrue(); assertThat(((HikariDataSource) dataSource).isClosed()).isTrue();
assertThat(((HikariDataSource) dataSource).getJdbcUrl()).isEqualTo("jdbc:hsqldb:mem:liquibase"); assertThat(((HikariDataSource) dataSource).getJdbcUrl()).isEqualTo("jdbc:hsqldb:mem:liquibase");
assertThat(((HikariDataSource) dataSource).getDriverClassName())
.isEqualTo("org.hsqldb.jdbc.JDBCDriver");
}));
}
@Test
void overrideDataSourceAndDriverClassName() {
String jdbcUrl = "jdbc:hsqldb:mem:liquibase";
String driverClassName = "org.hsqldb.jdbcDriver";
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.url:" + jdbcUrl,
"spring.liquibase.driver-class-name:" + driverClassName)
.run(assertLiquibase((liquibase) -> {
DataSource dataSource = liquibase.getDataSource();
assertThat(((HikariDataSource) dataSource).isClosed()).isTrue();
assertThat(((HikariDataSource) dataSource).getJdbcUrl()).isEqualTo(jdbcUrl);
assertThat(((HikariDataSource) dataSource).getDriverClassName()).isEqualTo(driverClassName);
}));
}
@Test
void overrideDataSourceWithFallbackDriverClassName() {
String jdbcUrl = "jdbc:hsqldb:mem:liquibase";
String driverClassName = "org.hsqldb.jdbcDriver";
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)
.withPropertyValues("spring.liquibase.url:" + jdbcUrl,
"spring.datasource.driver-class-name:" + driverClassName)
.run(assertLiquibase((liquibase) -> {
DataSource dataSource = liquibase.getDataSource();
assertThat(((HikariDataSource) dataSource).isClosed()).isTrue();
assertThat(((HikariDataSource) dataSource).getJdbcUrl()).isEqualTo(jdbcUrl);
assertThat(((HikariDataSource) dataSource).getDriverClassName()).isEqualTo(driverClassName);
})); }));
} }
......
...@@ -2217,7 +2217,7 @@ In addition to YAML, Liquibase also supports JSON, XML, and SQL change log forma ...@@ -2217,7 +2217,7 @@ In addition to YAML, Liquibase also supports JSON, XML, and SQL change log forma
By default, Liquibase autowires the (`@Primary`) `DataSource` in your context and uses that for migrations. By default, Liquibase autowires the (`@Primary`) `DataSource` in your context and uses that for migrations.
If you need to use a different `DataSource`, you can create one and mark its `@Bean` as `@LiquibaseDataSource`. If you need to use a different `DataSource`, you can create one and mark its `@Bean` as `@LiquibaseDataSource`.
If you do so and you want two data sources, remember to create another one and mark it as `@Primary`. If you do so and you want two data sources, remember to create another one and mark it as `@Primary`.
Alternatively, you can use Liquibase's native `DataSource` by setting `spring.liquibase.[url,user,password]` in external properties. Alternatively, you can use Liquibase's native `DataSource` by setting `spring.liquibase.[driver-class-name,url,user,password]` in external properties.
Setting either `spring.liquibase.url` or `spring.liquibase.user` is sufficient to cause Liquibase to use its own `DataSource`. Setting either `spring.liquibase.url` or `spring.liquibase.user` is sufficient to cause Liquibase to use its own `DataSource`.
If any of the three properties has not been set, the value of its equivalent `spring.datasource` property will be used. If any of the three properties has not been set, the value of its equivalent `spring.datasource` property will be used.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment