diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfiguration.java index e41414f5bb..a3c3947c16 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfiguration.java @@ -193,8 +193,8 @@ public class EndpointAutoConfiguration { @Bean @ConditionalOnMissingBean - public FlywayEndpoint flywayEndpoint(List flyway) { - return new FlywayEndpoint(flyway); + public FlywayEndpoint flywayEndpoint(Map flyways) { + return new FlywayEndpoint(flyways); } } @@ -206,8 +206,9 @@ public class EndpointAutoConfiguration { @Bean @ConditionalOnMissingBean - public LiquibaseEndpoint liquibaseEndpoint(List liquibase) { - return new LiquibaseEndpoint(liquibase); + public LiquibaseEndpoint liquibaseEndpoint( + Map liquibases) { + return new LiquibaseEndpoint(liquibases); } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/FlywayEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/FlywayEndpoint.java index f11b447a6d..8113081560 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/FlywayEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/FlywayEndpoint.java @@ -16,13 +16,9 @@ package org.springframework.boot.actuate.endpoint; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.Date; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,7 +27,7 @@ import org.flywaydb.core.api.MigrationInfo; import org.flywaydb.core.api.MigrationState; import org.flywaydb.core.api.MigrationType; -import org.springframework.boot.actuate.endpoint.FlywayEndpoint.FlywayMigration; +import org.springframework.boot.actuate.endpoint.FlywayEndpoint.FlywayReport; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.util.Assert; @@ -44,48 +40,54 @@ import org.springframework.util.Assert; * @since 1.3.0 */ @ConfigurationProperties(prefix = "endpoints.flyway") -public class FlywayEndpoint extends AbstractEndpoint>> { +public class FlywayEndpoint extends AbstractEndpoint> { - private final List flyway; + private final Map flyways; public FlywayEndpoint(Flyway flyway) { - this(Collections.singletonList(flyway)); + this(Collections.singletonMap("default", flyway)); } - public FlywayEndpoint(List flyway) { + public FlywayEndpoint(Map flyways) { super("flyway"); - Assert.notNull(flyway, "Flyway must not be null"); - this.flyway = flyway; + Assert.notEmpty(flyways, "Flyways must be specified"); + this.flyways = flyways; } @Override - public Map> invoke() { - Map> migrations = new HashMap>(); - for (Flyway flyway : this.flyway) { - Connection connection = null; - try { - connection = flyway.getDataSource().getConnection(); - DatabaseMetaData metaData = connection.getMetaData(); - - List migration = new ArrayList(); - for (MigrationInfo info : flyway.info().all()) { - migration.add(new FlywayMigration(info)); - } - migrations.put(metaData.getURL(), migration); - } - catch (SQLException e) { - //Continue - } - finally { - try { - connection.close(); - } - catch (SQLException e) { - //Continue - } + public List invoke() { + List reports = new ArrayList(); + for (Map.Entry entry : this.flyways.entrySet()) { + List migrations = new ArrayList(); + for (MigrationInfo info : entry.getValue().info().all()) { + migrations.add(new FlywayMigration(info)); } + reports.add(new FlywayReport(entry.getKey(), migrations)); + } + return reports; + } + + /** + * Flyway report for one datasource. + */ + public static class FlywayReport { + + private final String name; + private final List migrations; + + public FlywayReport(String name, List migrations) { + this.name = name; + this.migrations = migrations; + } + + public String getName() { + return this.name; } - return migrations; + + public List getMigrations() { + return this.migrations; + } + } /** diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/LiquibaseEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/LiquibaseEndpoint.java index 9e9fcfec19..a575daaa91 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/LiquibaseEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/LiquibaseEndpoint.java @@ -16,10 +16,8 @@ package org.springframework.boot.actuate.endpoint; -import java.sql.DatabaseMetaData; -import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -29,9 +27,9 @@ import liquibase.changelog.StandardChangeLogHistoryService; import liquibase.database.Database; import liquibase.database.DatabaseFactory; import liquibase.database.jvm.JdbcConnection; -import liquibase.exception.DatabaseException; import liquibase.integration.spring.SpringLiquibase; +import org.springframework.boot.actuate.endpoint.LiquibaseEndpoint.LiquibaseReport; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.util.Assert; @@ -42,50 +40,68 @@ import org.springframework.util.Assert; * @since 1.3.0 */ @ConfigurationProperties(prefix = "endpoints.liquibase") -public class LiquibaseEndpoint extends AbstractEndpoint>>> { +public class LiquibaseEndpoint extends AbstractEndpoint> { - private final List liquibase; + private final Map liquibases; public LiquibaseEndpoint(SpringLiquibase liquibase) { - this(Collections.singletonList(liquibase)); + this(Collections.singletonMap("default", liquibase)); } - public LiquibaseEndpoint(List liquibase) { + public LiquibaseEndpoint(Map liquibase) { super("liquibase"); - Assert.notNull(liquibase, "Liquibase must not be null"); - this.liquibase = liquibase; + Assert.notEmpty(liquibase, "Liquibase must be specified"); + this.liquibases = liquibase; } @Override - public Map>> invoke() { - Map>> services = new HashMap>>(); - + public List invoke() { + List reports = new ArrayList(); DatabaseFactory factory = DatabaseFactory.getInstance(); - - for (SpringLiquibase liquibase : this.liquibase) { - StandardChangeLogHistoryService service = new StandardChangeLogHistoryService(); + StandardChangeLogHistoryService service = new StandardChangeLogHistoryService(); + for (Map.Entry entry : this.liquibases.entrySet()) { try { - DatabaseMetaData metaData = liquibase.getDataSource().getConnection().getMetaData(); + DataSource dataSource = entry.getValue().getDataSource(); + JdbcConnection connection = new JdbcConnection(dataSource.getConnection()); try { - DataSource dataSource = liquibase.getDataSource(); - JdbcConnection connection = new JdbcConnection(dataSource.getConnection()); - try { - Database database = factory.findCorrectDatabaseImplementation(connection); - services.put(metaData.getURL(), service.queryDatabaseChangeLogTable(database)); - } - finally { - connection.close(); - } + Database database = factory.findCorrectDatabaseImplementation(connection); + reports.add(new LiquibaseReport(entry.getKey(), + service.queryDatabaseChangeLogTable(database))); } - catch (DatabaseException ex) { - throw new IllegalStateException("Unable to get Liquibase changelog", ex); + finally { + connection.close(); } } - catch (SQLException e) { - //Continue + catch (Exception ex) { + throw new IllegalStateException("Unable to get Liquibase changelog", ex); } } - return services; + + return reports; + } + + /** + * Liquibase report for one datasource. + */ + public static class LiquibaseReport { + + private final String name; + + private final List> changeLogs; + + public LiquibaseReport(String name, List> changeLogs) { + this.name = name; + this.changeLogs = changeLogs; + } + + public String getName() { + return this.name; + } + + public List> getChangeLogs() { + return this.changeLogs; + } + } }