Add options for Flyway to have its own DataSource
Either set flyway.[url,user,password] or create a DataSource @Bean and mark it @FlywayDataSource. Fixes gh-807
This commit is contained in:
parent
9f52a0dbd7
commit
32295b9bdc
|
@ -61,9 +61,13 @@ public class FlywayAutoConfiguration {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ResourceLoader resourceLoader = new DefaultResourceLoader();
|
private ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||||
|
|
||||||
@Autowired
|
@Autowired(required = false)
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
@FlywayDataSource
|
||||||
|
private DataSource flywayDataSource;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void checkLocationExists() {
|
public void checkLocationExists() {
|
||||||
if (this.properties.isCheckLocation()) {
|
if (this.properties.isCheckLocation()) {
|
||||||
|
@ -83,9 +87,19 @@ public class FlywayAutoConfiguration {
|
||||||
|
|
||||||
@Bean(initMethod = "migrate")
|
@Bean(initMethod = "migrate")
|
||||||
@ConfigurationProperties(prefix = "flyway")
|
@ConfigurationProperties(prefix = "flyway")
|
||||||
public Flyway flyway(DataSource dataSource) {
|
public Flyway flyway() {
|
||||||
Flyway flyway = new Flyway();
|
Flyway flyway = new Flyway();
|
||||||
flyway.setDataSource(dataSource);
|
if (this.properties.isCreateDataSource()) {
|
||||||
|
flyway.setDataSource(this.properties.getUrl(), this.properties.getUser(),
|
||||||
|
this.properties.getPassword(), this.properties.getInitSqls()
|
||||||
|
.toArray(new String[0]));
|
||||||
|
}
|
||||||
|
else if (this.flywayDataSource != null) {
|
||||||
|
flyway.setDataSource(this.flywayDataSource);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
flyway.setDataSource(this.dataSource);
|
||||||
|
}
|
||||||
return flyway;
|
return flyway;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2013 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
|
||||||
|
*
|
||||||
|
* http://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 java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Qualifier annotation for a DataSource to be injected in to Flyway. If used for a second
|
||||||
|
* data source, the other (main) one would normally be marked as <code>@Primary</code>.
|
||||||
|
*
|
||||||
|
* @author Dave Syer
|
||||||
|
*/
|
||||||
|
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
|
||||||
|
ElementType.ANNOTATION_TYPE })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Qualifier
|
||||||
|
public @interface FlywayDataSource {
|
||||||
|
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
package org.springframework.boot.autoconfigure.flyway;
|
package org.springframework.boot.autoconfigure.flyway;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.flywaydb.core.Flyway;
|
import org.flywaydb.core.Flyway;
|
||||||
|
@ -41,6 +42,14 @@ public class FlywayProperties {
|
||||||
|
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
private String user;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
private List<String> initSqls = Collections.emptyList();
|
||||||
|
|
||||||
public void setLocations(List<String> locations) {
|
public void setLocations(List<String> locations) {
|
||||||
this.locations = locations;
|
this.locations = locations;
|
||||||
}
|
}
|
||||||
|
@ -64,4 +73,40 @@ public class FlywayProperties {
|
||||||
public void setEnabled(boolean enabled) {
|
public void setEnabled(boolean enabled) {
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUser() {
|
||||||
|
return this.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(String user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return this.password == null ? "" : this.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return this.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getInitSqls() {
|
||||||
|
return this.initSqls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInitSqls(List<String> initSqls) {
|
||||||
|
this.initSqls = initSqls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCreateDataSource() {
|
||||||
|
return this.url != null && this.user != null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,8 @@ public class DataSourceBuilder {
|
||||||
|
|
||||||
private ClassLoader classLoader;
|
private ClassLoader classLoader;
|
||||||
|
|
||||||
|
private DriverClassNameProvider driverClassNameProvider = new DriverClassNameProvider();
|
||||||
|
|
||||||
private Map<String, String> properties = new HashMap<String, String>();
|
private Map<String, String> properties = new HashMap<String, String>();
|
||||||
|
|
||||||
public static DataSourceBuilder create() {
|
public static DataSourceBuilder create() {
|
||||||
|
@ -67,10 +69,19 @@ public class DataSourceBuilder {
|
||||||
public DataSource build() {
|
public DataSource build() {
|
||||||
Class<? extends DataSource> type = getType();
|
Class<? extends DataSource> type = getType();
|
||||||
DataSource result = BeanUtils.instantiate(type);
|
DataSource result = BeanUtils.instantiate(type);
|
||||||
|
maybeGetDriverClassName();
|
||||||
bind(result);
|
bind(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void maybeGetDriverClassName() {
|
||||||
|
if (!this.properties.containsKey("driverClassName")) {
|
||||||
|
String cls = this.driverClassNameProvider.getDriverClassName(this.properties
|
||||||
|
.get("url"));
|
||||||
|
this.properties.put("driverClassName", cls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void bind(DataSource result) {
|
private void bind(DataSource result) {
|
||||||
new RelaxedDataBinder(result).bind(getPropertyValues());
|
new RelaxedDataBinder(result).bind(getPropertyValues());
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ package org.springframework.boot.autoconfigure.flyway;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.flywaydb.core.Flyway;
|
import org.flywaydb.core.Flyway;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -26,12 +28,16 @@ import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
import org.springframework.beans.factory.BeanCreationException;
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
||||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link LiquibaseAutoConfiguration}.
|
* Tests for {@link LiquibaseAutoConfiguration}.
|
||||||
|
@ -66,6 +72,29 @@ public class FlywayAutoConfigurationTests {
|
||||||
assertEquals(0, this.context.getBeanNamesForType(Flyway.class).length);
|
assertEquals(0, this.context.getBeanNamesForType(Flyway.class).length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateDataSource() throws Exception {
|
||||||
|
EnvironmentTestUtils.addEnvironment(this.context,
|
||||||
|
"flyway.url:jdbc:hsqldb:mem:flywaytest", "flyway.user:sa");
|
||||||
|
this.context
|
||||||
|
.register(EmbeddedDataSourceConfiguration.class,
|
||||||
|
FlywayAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
|
this.context.refresh();
|
||||||
|
Flyway flyway = this.context.getBean(Flyway.class);
|
||||||
|
assertNotNull(flyway.getDataSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFlywayDataSource() throws Exception {
|
||||||
|
this.context.register(FlywayDataSourceConfiguration.class,
|
||||||
|
EmbeddedDataSourceConfiguration.class, FlywayAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
|
this.context.refresh();
|
||||||
|
Flyway flyway = this.context.getBean(Flyway.class);
|
||||||
|
assertNotNull(flyway.getDataSource());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultFlyway() throws Exception {
|
public void testDefaultFlyway() throws Exception {
|
||||||
this.context
|
this.context
|
||||||
|
@ -113,4 +142,16 @@ public class FlywayAutoConfigurationTests {
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
protected static class FlywayDataSourceConfiguration {
|
||||||
|
|
||||||
|
@FlywayDataSource
|
||||||
|
@Bean
|
||||||
|
public DataSource flywayDataSource() {
|
||||||
|
return DataSourceBuilder.create().url("jdbc:hsqldb:mem:flywaytest")
|
||||||
|
.username("sa").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,6 +203,9 @@ content into your application; rather pick only the properties that you need.
|
||||||
flyway.prefix=V
|
flyway.prefix=V
|
||||||
flyway.suffix=.sql
|
flyway.suffix=.sql
|
||||||
flyway.enabled=true
|
flyway.enabled=true
|
||||||
|
flyway.url= # JDBC url if you want Flyway to create its own DataSource
|
||||||
|
flyway.user= # JDBC username if you want Flyway to create its own DataSource
|
||||||
|
flyway.password= # JDBC password if you want Flyway to create its own DataSource
|
||||||
|
|
||||||
# LIQUIBASE ({sc-spring-boot-autoconfigure}/liquibase/LiquibaseProperties.{sc-ext}[LiquibaseProperties])
|
# LIQUIBASE ({sc-spring-boot-autoconfigure}/liquibase/LiquibaseProperties.{sc-ext}[LiquibaseProperties])
|
||||||
liquibase.change-log=classpath:/db/changelog/db.changelog-master.yaml
|
liquibase.change-log=classpath:/db/changelog/db.changelog-master.yaml
|
||||||
|
|
|
@ -974,13 +974,13 @@ JDBC or JPA (then that one will be picked up by any `@Autowired` injections).
|
||||||
@Primary
|
@Primary
|
||||||
@ConfigurationProperties(prefix="datasource.primary")
|
@ConfigurationProperties(prefix="datasource.primary")
|
||||||
public DataSource primaryDataSource() {
|
public DataSource primaryDataSource() {
|
||||||
return new FancyDataSource();
|
return DataSourceBuilder.create().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConfigurationProperties(prefix="datasource.secondary")
|
@ConfigurationProperties(prefix="datasource.secondary")
|
||||||
public DataSource secondaryDataSource() {
|
public DataSource secondaryDataSource() {
|
||||||
return new FancyDataSource();
|
return DataSourceBuilder.create().build();
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -1207,6 +1207,13 @@ addition Spring Boot provides a small set of properties in
|
||||||
{sc-spring-boot-autoconfigure}/flyway/FlywayProperties.{sc-ext}[`FlywayProperties`]
|
{sc-spring-boot-autoconfigure}/flyway/FlywayProperties.{sc-ext}[`FlywayProperties`]
|
||||||
that can be used to disable the migrations, or switch off the location checking.
|
that can be used to disable the migrations, or switch off the location checking.
|
||||||
|
|
||||||
|
By default Flyway will autowire the (`@Primary`) `DataSource` in your context and
|
||||||
|
use that for migrations. If you like to use a different `DataSource` you can create
|
||||||
|
one and mark its `@Bean` as `@FlywayDataSource` - if you do that remember to create
|
||||||
|
another one and mark it as `@Primary` if you want 2 data sources.
|
||||||
|
Or you can use Flyway's native `DataSource` by setting `flyway.[url,user,password]`
|
||||||
|
in external properties.
|
||||||
|
|
||||||
There is a {github-code}/spring-boot-samples/spring-boot-sample-flyway[Flyway sample] so
|
There is a {github-code}/spring-boot-samples/spring-boot-sample-flyway[Flyway sample] so
|
||||||
you can see how to set things up.
|
you can see how to set things up.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue