diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml
index 10b7554350c..d7441c94890 100644
--- a/spring-boot-actuator/pom.xml
+++ b/spring-boot-actuator/pom.xml
@@ -112,6 +112,11 @@
activemq-broker
true
+
+ org.flywaydb
+ flyway-core
+ true
+
org.hibernate
hibernate-validator
@@ -122,6 +127,11 @@
infinispan-spring4
true
+
+ org.liquibase
+ liquibase-core
+ true
+
org.springframework
spring-messaging
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 308462d400b..591aaf5dd2c 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
@@ -25,6 +25,9 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
+import liquibase.integration.spring.SpringLiquibase;
+
+import org.flywaydb.core.Flyway;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint;
@@ -33,8 +36,10 @@ import org.springframework.boot.actuate.endpoint.ConfigurationPropertiesReportEn
import org.springframework.boot.actuate.endpoint.DumpEndpoint;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint;
+import org.springframework.boot.actuate.endpoint.FlywayEndpoint;
import org.springframework.boot.actuate.endpoint.HealthEndpoint;
import org.springframework.boot.actuate.endpoint.InfoEndpoint;
+import org.springframework.boot.actuate.endpoint.LiquibaseEndpoint;
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
import org.springframework.boot.actuate.endpoint.PublicMetrics;
import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
@@ -45,12 +50,15 @@ import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
import org.springframework.boot.actuate.trace.InMemoryTraceRepository;
import org.springframework.boot.actuate.trace.TraceRepository;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
+import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
+import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.boot.bind.PropertiesConfigurationFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -70,8 +78,10 @@ import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
* @author Greg Turnquist
* @author Christian Dupuis
* @author Stephane Nicoll
+ * @author Eddú Meléndez
*/
@Configuration
+@AutoConfigureAfter({ FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class })
public class EndpointAutoConfiguration {
@Autowired
@@ -161,6 +171,32 @@ public class EndpointAutoConfiguration {
return new ConfigurationPropertiesReportEndpoint();
}
+ @Configuration
+ @ConditionalOnBean(Flyway.class)
+ @ConditionalOnClass(Flyway.class)
+ static class FlywayEndpointConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public FlywayEndpoint flywayEndpoint(Flyway flyway) {
+ return new FlywayEndpoint(flyway);
+ }
+
+ }
+
+ @Configuration
+ @ConditionalOnBean(SpringLiquibase.class)
+ @ConditionalOnClass(SpringLiquibase.class)
+ static class LiquibaseEndpointConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public LiquibaseEndpoint liquibaseEndpoint(SpringLiquibase liquibase) {
+ return new LiquibaseEndpoint(liquibase);
+ }
+
+ }
+
@Configuration
@ConditionalOnClass(AbstractHandlerMethodMapping.class)
protected static class RequestMappingEndpointConfiguration {
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
new file mode 100644
index 00000000000..c18b3534bc4
--- /dev/null
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/FlywayEndpoint.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2012-2015 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.actuate.endpoint;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.flywaydb.core.Flyway;
+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.context.properties.ConfigurationProperties;
+import org.springframework.util.Assert;
+
+/**
+ * {@link Endpoint} to expose flyway info.
+ *
+ * @author Eddú Meléndez
+ * @author Phillip Webb
+ * @since 1.3.0
+ */
+@ConfigurationProperties(prefix = "endpoints.flyway", ignoreUnknownFields = true)
+public class FlywayEndpoint extends AbstractEndpoint> {
+
+ private final Flyway flyway;
+
+ public FlywayEndpoint(Flyway flyway) {
+ super("flyway");
+ Assert.notNull(flyway, "Flyway must not be null");
+ this.flyway = flyway;
+ }
+
+ @Override
+ public List invoke() {
+ List migrations = new ArrayList();
+ for (MigrationInfo info : this.flyway.info().all()) {
+ migrations.add(new FlywayMigration(info));
+ }
+ return migrations;
+ }
+
+ public static class FlywayMigration {
+
+ private MigrationType type;
+
+ private Integer checksum;
+
+ private String version;
+
+ private String description;
+
+ private String script;
+
+ private MigrationState state;
+
+ private Date installedOn;
+
+ private Integer executionTime;
+
+ public FlywayMigration(MigrationInfo info) {
+ this.type = info.getType();
+ this.checksum = info.getChecksum();
+ this.version = info.getVersion().toString();
+ this.description = info.getDescription();
+ this.script = info.getScript();
+ this.state = info.getState();
+ this.installedOn = info.getInstalledOn();
+ this.executionTime = info.getExecutionTime();
+ }
+
+ public MigrationType getType() {
+ return this.type;
+ }
+
+ public Integer getChecksum() {
+ return this.checksum;
+ }
+
+ public String getVersion() {
+ return this.version;
+ }
+
+ public String getDescription() {
+ return this.description;
+ }
+
+ public String getScript() {
+ return this.script;
+ }
+
+ public MigrationState getState() {
+ return this.state;
+ }
+
+ public Date getInstalledOn() {
+ return this.installedOn;
+ }
+
+ public Integer getExecutionTime() {
+ return this.executionTime;
+ }
+
+ }
+
+}
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
new file mode 100644
index 00000000000..d96a99973a3
--- /dev/null
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/LiquibaseEndpoint.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2012-2015 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.actuate.endpoint;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import liquibase.changelog.StandardChangeLogHistoryService;
+import liquibase.database.Database;
+import liquibase.database.DatabaseFactory;
+import liquibase.database.jvm.JdbcConnection;
+import liquibase.integration.spring.SpringLiquibase;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.util.Assert;
+
+/**
+ * {@link Endpoint} to expose liquibase info.
+ *
+ * @author Eddú Meléndez
+ * @since 1.3.0
+ */
+@ConfigurationProperties(prefix = "endpoints.liquibase", ignoreUnknownFields = true)
+public class LiquibaseEndpoint extends AbstractEndpoint>> {
+
+ private final SpringLiquibase liquibase;
+
+ public LiquibaseEndpoint(SpringLiquibase liquibase) {
+ super("liquibase");
+ Assert.notNull(liquibase, "Liquibase must not be null");
+ this.liquibase = liquibase;
+ }
+
+ @Override
+ public List