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
|
||||
private ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
private DataSource dataSource;
|
||||
|
||||
@Autowired(required = false)
|
||||
@FlywayDataSource
|
||||
private DataSource flywayDataSource;
|
||||
|
||||
@PostConstruct
|
||||
public void checkLocationExists() {
|
||||
if (this.properties.isCheckLocation()) {
|
||||
|
@ -83,9 +87,19 @@ public class FlywayAutoConfiguration {
|
|||
|
||||
@Bean(initMethod = "migrate")
|
||||
@ConfigurationProperties(prefix = "flyway")
|
||||
public Flyway flyway(DataSource dataSource) {
|
||||
public Flyway 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.flywaydb.core.Flyway;
|
||||
|
@ -41,6 +42,14 @@ public class FlywayProperties {
|
|||
|
||||
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) {
|
||||
this.locations = locations;
|
||||
}
|
||||
|
@ -64,4 +73,40 @@ public class FlywayProperties {
|
|||
public void setEnabled(boolean 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 DriverClassNameProvider driverClassNameProvider = new DriverClassNameProvider();
|
||||
|
||||
private Map<String, String> properties = new HashMap<String, String>();
|
||||
|
||||
public static DataSourceBuilder create() {
|
||||
|
@ -67,10 +69,19 @@ public class DataSourceBuilder {
|
|||
public DataSource build() {
|
||||
Class<? extends DataSource> type = getType();
|
||||
DataSource result = BeanUtils.instantiate(type);
|
||||
maybeGetDriverClassName();
|
||||
bind(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) {
|
||||
new RelaxedDataBinder(result).bind(getPropertyValues());
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ package org.springframework.boot.autoconfigure.flyway;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
@ -26,12 +28,16 @@ import org.junit.Test;
|
|||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
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.liquibase.LiquibaseAutoConfiguration;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
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.assertNotNull;
|
||||
|
||||
/**
|
||||
* Tests for {@link LiquibaseAutoConfiguration}.
|
||||
|
@ -66,6 +72,29 @@ public class FlywayAutoConfigurationTests {
|
|||
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
|
||||
public void testDefaultFlyway() throws Exception {
|
||||
this.context
|
||||
|
@ -113,4 +142,16 @@ public class FlywayAutoConfigurationTests {
|
|||
PropertyPlaceholderAutoConfiguration.class);
|
||||
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.suffix=.sql
|
||||
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.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
|
||||
@ConfigurationProperties(prefix="datasource.primary")
|
||||
public DataSource primaryDataSource() {
|
||||
return new FancyDataSource();
|
||||
return DataSourceBuilder.create().build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix="datasource.secondary")
|
||||
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`]
|
||||
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
|
||||
you can see how to set things up.
|
||||
|
||||
|
|
Loading…
Reference in New Issue