diff --git a/.travis.yml b/.travis.yml
index da98449..1dde844 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -36,3 +36,13 @@ env:
global:
- secure: "t/DJwSV2TUQ2OxZBqDhWl1noCYqJkWGngSvcWMct5z4gcuNScg5Pw5ylBzNCl43lF045X9nOJdY40uH2UyNd1nwNW1XNehuJCgijU3rFX1xl/7rAq52B4FpECQhrwwzInpa5um/84Uwl61GghKqyFbxyGuxq7jzFSQl1vPmBuRdbKkkufr5APcIu5Ger9b1E7T9Crkcpv/u624T2Zz8Hxb8ezemAOK8fW9rTGLx044bjhCpubXoeYXdIuzKd0LxK5pop4ozoGZ5/L3DVB5JhXMrXi99Gjf+BPdiLTCChenU6H6kaqP//lOYRseRsn7kMT1i9zt5lfmn3udFgTekRjSDcz9YFwls/OjAo7rT0i8g7Rq68DiNJKojcKTB7Pp5j+PNVXru+QljvY/oFAfkWBUukKLemNALli2taStaXlfvRHeb+d5AnCPalwwOfNm6nkQJzkDxTxD6UlGj4IzTYQ1oxoAxkw7AIxKu9yp6zTgYX0OXHaioAdnpVYFUq9nIMUWVts957DVNHMTAbjXchyaG9Gsv8gE0iQN7hURhWnmrS+bQnWVlhrUYuIyavbDXVvHSzycEU59PNfGUFK+x7XujhWosmE6kHbSgJxZAF4SGxzCJpxOqrJTWjgYKgPwZ4yg2OFiQ04u8umqsFxHjvh02e9iG3OAA2l9F0L5A6jA8="
- secure: "CdB/iOvwr1UmoFn762u2vgru4J7Hyn+YO0KjWooe6k0VD6TNm7HIWYXyGSH/J3chO5BdzYv2TxnWFHaeTMq+84+MIBp/TfV3UfSX8pMuspvfqFtNcj7l2HCt9WJ95t4zvwyJjSR5lN6C2LIGrkztkx65uPi6SXqJUJnswMwjeftFfChTh05JprdZ5V8T/ArJzGLmy+EgqaNYR2lwtYUNf8MudTZgri9vVkECeO2c+V0/ELW5/+L/Qb1XnLcubPvMVfrxhuer8+YjLTDusjnIj9iwuLU5+kZM7uoAJDqLKHSSvruEtz2lMLNooEnINkJanNiRvpkfHLojJz0dAebdiuU47yz4Qpg1XFPGHwjDJvO0uL+C+DwGmKZ3kuWug+d6/5HtAcsSntdHxQhG0CoN48k7GkITTAdiTLmnzG+FBmUHswFP8bFZr24srMOuzWzCRr+xsKp93XWDHY+I93FnsBIEwWkqWjuwQUuEDv/6CGxRrdTk1Q8z/b6Ex/973cKFXRUnhwjQ2cBo+bScfRmUaMJBYSbY1yVGMDCyRtcpTClnhlzuQbXNVHxRMvREidRZkqM0C+LcERfHVzMaQ2QatYw1F0WCFSl8J5gjDNMwtHz0GU9t5gvLr7hogk2Jl8baBEI3LvkbANNz/mLP2oid4bZQmkmw9krQFZc/esLWFMI="
+
+# to be able to see where it goes wrong (see also https://github.com/travis-ci/travis-ci/issues/6018)
+after_failure:
+ - echo == Begin of test log(s) ==
+ - for f in $(find . -name test.log); do echo "test log: $f"; cat $f; sleep 1; done
+ - echo == End of test log(s) ==
+
+# give some time to spool the output
+after_script:
+ - sleep 1
diff --git a/bootique-flyway/pom.xml b/bootique-flyway/pom.xml
index 341f09f..2706daa 100644
--- a/bootique-flyway/pom.xml
+++ b/bootique-flyway/pom.xml
@@ -35,6 +35,10 @@
Provides Flyway integration with Bootique.
+
+ 3.2.0
+
+
@@ -119,4 +123,22 @@
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${maven-jar-plugin.version}
+
+
+
+ test-jar
+
+
+
+
+
+
+
diff --git a/bootique-flyway/src/main/java/io/bootique/flyway/FlywayRunner.java b/bootique-flyway/src/main/java/io/bootique/flyway/FlywayRunner.java
index 62a4d01..d529400 100644
--- a/bootique-flyway/src/main/java/io/bootique/flyway/FlywayRunner.java
+++ b/bootique-flyway/src/main/java/io/bootique/flyway/FlywayRunner.java
@@ -20,16 +20,19 @@
package io.bootique.flyway;
import org.flywaydb.core.Flyway;
-import org.flywaydb.core.api.MigrationInfoService;
import org.flywaydb.core.api.MigrationInfo;
+import org.flywaydb.core.api.MigrationInfoService;
import org.flywaydb.core.api.MigrationVersion;
+import org.flywaydb.core.internal.info.MigrationInfoDumper;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.flywaydb.core.internal.info.MigrationInfoDumper;
import java.util.function.Consumer;
public class FlywayRunner {
+ private static Logger logger = LoggerFactory.getLogger(FlywayRunner.class);
+
private final FlywaySettings settings;
public FlywayRunner(FlywaySettings settings) {
@@ -66,8 +69,6 @@ public void info() {
MigrationVersion schemaVersionToOutput = currentSchemaVersion == null ? MigrationVersion.EMPTY : currentSchemaVersion;
- final Logger logger = LoggerFactory.getLogger(FlywayRunner.class);
-
if(logger.isInfoEnabled()) {
logger.info("Schema version: " + schemaVersionToOutput);
logger.info("");
@@ -90,6 +91,7 @@ private void forEach(Consumer flywayConsumer) {
.dataSource(ds)
.configuration(settings.getProperties()) // takes precedence over location settings (do not use jdbc connection details though in a Flyway configuration file)
);
+
flywayConsumer.accept(flyway);
});
}
diff --git a/bootique-flyway/src/main/java/io/bootique/flyway/FlywaySettings.java b/bootique-flyway/src/main/java/io/bootique/flyway/FlywaySettings.java
index d481bff..b21e076 100644
--- a/bootique-flyway/src/main/java/io/bootique/flyway/FlywaySettings.java
+++ b/bootique-flyway/src/main/java/io/bootique/flyway/FlywaySettings.java
@@ -21,17 +21,25 @@
import io.bootique.resource.ResourceFactory;
-import javax.sql.DataSource;
+import java.io.*;
+import java.net.URL;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.HashMap;
-import java.io.*;
-import java.net.URL;
+import java.util.TreeMap;
+import javax.sql.DataSource;
+import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.internal.configuration.ConfigUtils;
+import org.flywaydb.core.internal.util.StringUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class FlywaySettings {
+ private static Logger logger = LoggerFactory.getLogger(FlywayRunner.class);
+
private final List dataSources;
private final String[] locations;
private final String[] configFiles; // list of config files to use
@@ -55,19 +63,39 @@ public String[] getLocations() {
public java.util.Map getProperties() {
Map config = new HashMap();
- try {
- for (String file : this.configFiles) {
- URL url = new ResourceFactory(file).getUrl(); // file may have classpath: as a prefix
-
- Reader reader = new InputStreamReader(url.openStream());
- config.putAll(ConfigUtils.loadConfigurationFromReader(reader));
+ for (String file : this.configFiles) {
+ final String errorMessage = "Unable to load config file: " + file;
+
+ try {
+ final URL url = new ResourceFactory(file).getUrl(); // file may have classpath: as a prefix
+ final Reader reader = new InputStreamReader(url.openStream());
+
+ final Map fileConfig = ConfigUtils.loadConfigurationFromReader(reader);
+
+ config.putAll(fileConfig);
+ dumpConfiguration(fileConfig, file);
+ } catch(IOException e) {
+ throw new FlywayException(errorMessage, e);
}
- } catch(IOException e) {
- throw new RuntimeException(e);
}
- ConfigUtils.dumpConfiguration(config);
+ dumpConfiguration(config, "ALL");
return config;
}
+
+ /**
+ * Dumps the configuration to the console when debug output is activated.
+ *
+ * @param config The configured properties.
+ * @param resource The config file resource.
+ */
+ private static void dumpConfiguration(Map config, String resource) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Using configuration resource " + resource);
+ for (Map.Entry entry : new TreeMap<>(config).entrySet()) {
+ logger.debug(entry.getKey() + " -> " + entry.getValue());
+ }
+ }
+ }
}
diff --git a/bootique-flyway5/pom.xml b/bootique-flyway5/pom.xml
new file mode 100644
index 0000000..a452b8f
--- /dev/null
+++ b/bootique-flyway5/pom.xml
@@ -0,0 +1,139 @@
+
+
+
+
+ 4.0.0
+
+
+ io.bootique.flyway
+ bootique-flyway-parent
+ 2.0.B1-SNAPSHOT
+
+
+ bootique-flyway5
+ jar
+
+ bootique-flyway: Flyway5 Integration with Bootique
+
+ Provides Flyway5 integration with Bootique.
+
+
+
+ 5.1.4
+
+
+
+
+
+ io.bootique
+ bootique
+ compile
+
+
+ io.bootique.jdbc
+ bootique-jdbc
+ compile
+
+
+ org.flywaydb
+ flyway-core
+ compile
+
+
+ org.slf4j
+ slf4j-api
+ compile
+
+
+ io.bootique.flyway
+ bootique-flyway
+ ${project.parent.version}
+
+
+
+
+ junit
+ junit
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ io.bootique
+ bootique-test
+ test
+
+
+ com.h2database
+ h2
+ test
+
+
+ io.bootique.jdbc
+ bootique-jdbc-test
+ test
+
+
+ io.bootique.jdbc
+ bootique-jdbc-tomcat
+ test
+
+
+ io.bootique.logback
+ bootique-logback
+ test
+
+
+ io.bootique.flyway
+ bootique-flyway
+ ${project.parent.version}
+ tests
+ test-jar
+ test
+
+
+
+
+
+
+ gpg
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+
+
+
+
diff --git a/bootique-flyway5/src/main/java/io/bootique/flyway/FlywayRunner.java b/bootique-flyway5/src/main/java/io/bootique/flyway/FlywayRunner.java
new file mode 100644
index 0000000..dbec38a
--- /dev/null
+++ b/bootique-flyway5/src/main/java/io/bootique/flyway/FlywayRunner.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to ObjectStyle LLC under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ObjectStyle LLC licenses
+ * this file to you 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 io.bootique.flyway;
+
+import org.flywaydb.core.Flyway;
+import org.flywaydb.core.api.MigrationInfo;
+import org.flywaydb.core.api.MigrationInfoService;
+import org.flywaydb.core.api.MigrationVersion;
+import org.flywaydb.core.api.configuration.FluentConfiguration;
+import org.flywaydb.core.internal.info.MigrationInfoDumper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.function.Consumer;
+
+public class FlywayRunner {
+ private static Logger logger = LoggerFactory.getLogger(FlywayRunner.class);
+
+ private final FlywaySettings settings;
+
+ public FlywayRunner(FlywaySettings settings) {
+ this.settings = settings;
+ }
+
+ public void migrate() {
+ forEach(Flyway::migrate);
+ }
+
+ public void validate() {
+ forEach(Flyway::validate);
+ }
+
+ public void baseline() {
+ forEach(Flyway::baseline);
+ }
+
+ public void repair() {
+ forEach(Flyway::repair);
+ }
+
+ public void info() {
+ settings.getDataSources().forEach(ds -> {
+ FluentConfiguration configuration = new FluentConfiguration();
+
+ Flyway flyway = new Flyway(configuration
+ .locations(settings.getLocations())
+ .dataSource(ds)
+ .configure(settings.getProperties()) // takes precedence over location settings (do not use jdbc connection details though in a Flyway configuration file)
+ );
+
+ MigrationInfoService info = flyway.info();
+ MigrationInfo current = info.current();
+ MigrationVersion currentSchemaVersion = current == null ? MigrationVersion.EMPTY : current.getVersion();
+
+ MigrationVersion schemaVersionToOutput = currentSchemaVersion == null ? MigrationVersion.EMPTY : currentSchemaVersion;
+
+ if(logger.isInfoEnabled()) {
+ logger.info("Schema version: " + schemaVersionToOutput);
+ logger.info("");
+
+ for (String line : MigrationInfoDumper.dumpToAsciiTable(info.all()).split("\\r?\\n")) {
+ logger.info(line);
+ }
+ }
+ });
+ }
+
+ public void clean() {
+ forEach(Flyway::clean);
+ }
+
+ private void forEach(Consumer flywayConsumer) {
+ settings.getDataSources().forEach(ds -> {
+ FluentConfiguration configuration = new FluentConfiguration();
+
+ Flyway flyway = new Flyway(configuration
+ .locations(settings.getLocations())
+ .dataSource(ds)
+ .configure(settings.getProperties()) // takes precedence over location settings (do not use jdbc connection details though in a Flyway configuration file)
+ );
+
+ flywayConsumer.accept(flyway);
+ });
+ }
+}
diff --git a/bootique-flyway5/src/main/java/io/bootique/flyway/FlywaySettings.java b/bootique-flyway5/src/main/java/io/bootique/flyway/FlywaySettings.java
new file mode 100644
index 0000000..cb509cd
--- /dev/null
+++ b/bootique-flyway5/src/main/java/io/bootique/flyway/FlywaySettings.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to ObjectStyle LLC under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ObjectStyle LLC licenses
+ * this file to you 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 io.bootique.flyway;
+
+import io.bootique.resource.ResourceFactory;
+
+import java.io.*;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TreeMap;
+import javax.sql.DataSource;
+
+import org.flywaydb.core.api.FlywayException;
+import org.flywaydb.core.internal.configuration.ConfigUtils;
+import org.flywaydb.core.internal.util.FileCopyUtils;
+import org.flywaydb.core.internal.util.StringUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FlywaySettings {
+ private static Logger logger = LoggerFactory.getLogger(FlywayRunner.class);
+
+ private final List dataSources;
+ private final String[] locations;
+ private final String[] configFiles; // list of config files to use
+
+ public FlywaySettings(List dataSources,
+ List locations,
+ List configFiles) {
+ this.dataSources = Collections.unmodifiableList(dataSources);
+ this.locations = locations.toArray(new String[0]);
+ this.configFiles = configFiles.toArray(new String[0]);
+ }
+
+ public List getDataSources() {
+ return dataSources;
+ }
+
+ public String[] getLocations() {
+ return locations;
+ }
+
+ public java.util.Map getProperties() {
+ Map config = new HashMap();
+
+ for (String file : this.configFiles) {
+ final String errorMessage = "Unable to load config file: " + file;
+
+ try {
+ final URL url = new ResourceFactory(file).getUrl(); // file may have classpath: as a prefix
+ final Reader reader = new InputStreamReader(url.openStream());
+
+ // loadConfigurationFromReader() only available for Flyway 6
+ // config.putAll(ConfigUtils.loadConfigurationFromReader(reader));
+
+ final String contents = FileCopyUtils.copyToString(reader);
+ final Properties properties = new Properties();
+
+ properties.load(new StringReader(contents.replace("\\", "\\\\")));
+
+ final Map fileConfig = ConfigUtils.propertiesToMap(properties);
+
+ config.putAll(fileConfig);
+ dumpConfiguration(fileConfig, file);
+ } catch(IOException e) {
+ throw new FlywayException(errorMessage, e);
+ }
+ }
+
+ dumpConfiguration(config, "ALL");
+
+ return config;
+ }
+
+ /**
+ * Dumps the configuration to the console when debug output is activated.
+ *
+ * @param config The configured properties.
+ * @param resource The config file resource.
+ */
+ private static void dumpConfiguration(Map config, String resource) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Using configuration resource " + resource);
+ for (Map.Entry entry : new TreeMap<>(config).entrySet()) {
+ logger.debug(entry.getKey() + " -> " + entry.getValue());
+ }
+ }
+ }
+}
diff --git a/bootique-flyway5/src/test/java/db/migration/V2__Update_table.java b/bootique-flyway5/src/test/java/db/migration/V2__Update_table.java
new file mode 100644
index 0000000..c5e3967
--- /dev/null
+++ b/bootique-flyway5/src/test/java/db/migration/V2__Update_table.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to ObjectStyle LLC under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ObjectStyle LLC licenses
+ * this file to you 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 db.migration;
+
+import org.flywaydb.core.api.migration.jdbc.JdbcMigration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+public class V2__Update_table implements JdbcMigration {
+ private static Logger LOGGER = LoggerFactory.getLogger(V2__Update_table.class);
+
+ @Override
+ public void migrate(Connection connection) {
+ String insertSQL = "INSERT INTO TEST (id, name) VALUES (2, 'Test 2')";
+
+ try (PreparedStatement statement = connection.prepareStatement(insertSQL)) {
+ statement.execute();
+ } catch (SQLException e) {
+ LOGGER.error("Migration failed", e);
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/bootique-flyway5/src/test/java/path/migration/V2__Update_table_nonDefault.java b/bootique-flyway5/src/test/java/path/migration/V2__Update_table_nonDefault.java
new file mode 100644
index 0000000..70693ce
--- /dev/null
+++ b/bootique-flyway5/src/test/java/path/migration/V2__Update_table_nonDefault.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to ObjectStyle LLC under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ObjectStyle LLC licenses
+ * this file to you 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 path.migration;
+
+import db.migration.V2__Update_table;
+import org.flywaydb.core.api.migration.jdbc.JdbcMigration;
+
+import java.sql.Connection;
+
+public class V2__Update_table_nonDefault implements JdbcMigration {
+
+ @Override
+ public void migrate(Connection connection) {
+ new V2__Update_table().migrate(connection);
+ }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 31e83b0..b45c75f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,11 +39,12 @@
bootique-flyway
+ bootique-flyway5
${project.version}
- 6.5.0
+ 6.5.5
1.4.200