Merge pull request #3435 from eddumelendez/gh-3434

* pr/3435:
  Add flyway and liquibase endpoint documentation
  Add 'flyway' and 'liquibase' actuator endpoints
  Add serialization endpoint tests
pull/3452/head
Phillip Webb 10 years ago
commit 52643529a3

@ -112,6 +112,11 @@
<artifactId>activemq-broker</artifactId> <artifactId>activemq-broker</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.hibernate</groupId> <groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId> <artifactId>hibernate-validator</artifactId>
@ -122,6 +127,11 @@
<artifactId>infinispan-spring4</artifactId> <artifactId>infinispan-spring4</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId> <artifactId>spring-messaging</artifactId>

@ -25,6 +25,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; 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.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint; 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.DumpEndpoint;
import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint; 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.HealthEndpoint;
import org.springframework.boot.actuate.endpoint.InfoEndpoint; 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.MetricsEndpoint;
import org.springframework.boot.actuate.endpoint.PublicMetrics; import org.springframework.boot.actuate.endpoint.PublicMetrics;
import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint; 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.health.OrderedHealthAggregator;
import org.springframework.boot.actuate.trace.InMemoryTraceRepository; import org.springframework.boot.actuate.trace.InMemoryTraceRepository;
import org.springframework.boot.actuate.trace.TraceRepository; import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport; import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.SearchStrategy; 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.boot.bind.PropertiesConfigurationFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -70,8 +78,10 @@ import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
* @author Greg Turnquist * @author Greg Turnquist
* @author Christian Dupuis * @author Christian Dupuis
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Eddú Meléndez
*/ */
@Configuration @Configuration
@AutoConfigureAfter({ FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class })
public class EndpointAutoConfiguration { public class EndpointAutoConfiguration {
@Autowired @Autowired
@ -161,6 +171,32 @@ public class EndpointAutoConfiguration {
return new ConfigurationPropertiesReportEndpoint(); 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 @Configuration
@ConditionalOnClass(AbstractHandlerMethodMapping.class) @ConditionalOnClass(AbstractHandlerMethodMapping.class)
protected static class RequestMappingEndpointConfiguration { protected static class RequestMappingEndpointConfiguration {

@ -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<List<FlywayMigration>> {
private final Flyway flyway;
public FlywayEndpoint(Flyway flyway) {
super("flyway");
Assert.notNull(flyway, "Flyway must not be null");
this.flyway = flyway;
}
@Override
public List<FlywayMigration> invoke() {
List<FlywayMigration> migrations = new ArrayList<FlywayMigration>();
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;
}
}
}

@ -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<List<Map<String, ?>>> {
private final SpringLiquibase liquibase;
public LiquibaseEndpoint(SpringLiquibase liquibase) {
super("liquibase");
Assert.notNull(liquibase, "Liquibase must not be null");
this.liquibase = liquibase;
}
@Override
public List<Map<String, ?>> invoke() {
StandardChangeLogHistoryService service = new StandardChangeLogHistoryService();
try {
DatabaseFactory factory = DatabaseFactory.getInstance();
DataSource dataSource = this.liquibase.getDataSource();
JdbcConnection connection = new JdbcConnection(dataSource.getConnection());
Database database = factory.findCorrectDatabaseImplementation(connection);
return service.queryDatabaseChangeLogTable(database);
}
catch (Exception ex) {
throw new IllegalStateException("Unable to get Liquibase changelog", ex);
}
}
}

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2014 the original author or authors. * Copyright 2012-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,8 +26,10 @@ import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint
import org.springframework.boot.actuate.endpoint.BeansEndpoint; import org.springframework.boot.actuate.endpoint.BeansEndpoint;
import org.springframework.boot.actuate.endpoint.DumpEndpoint; import org.springframework.boot.actuate.endpoint.DumpEndpoint;
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint; 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.HealthEndpoint;
import org.springframework.boot.actuate.endpoint.InfoEndpoint; 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.MetricsEndpoint;
import org.springframework.boot.actuate.endpoint.PublicMetrics; import org.springframework.boot.actuate.endpoint.PublicMetrics;
import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint; import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
@ -36,7 +38,9 @@ import org.springframework.boot.actuate.endpoint.TraceEndpoint;
import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.metrics.Metric; import org.springframework.boot.actuate.metrics.Metric;
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport; import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
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.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.Bean;
@ -55,6 +59,7 @@ import static org.junit.Assert.assertTrue;
* @author Greg Turnquist * @author Greg Turnquist
* @author Christian Dupuis * @author Christian Dupuis
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Eddú Meléndez
*/ */
public class EndpointAutoConfigurationTests { public class EndpointAutoConfigurationTests {
@ -156,6 +161,28 @@ public class EndpointAutoConfigurationTests {
assertNull(endpoint.invoke().get("git")); assertNull(endpoint.invoke().get("git"));
} }
@Test
public void testFlywayEndpoint() {
this.context = new AnnotationConfigApplicationContext();
this.context.register(EmbeddedDataSourceConfiguration.class,
FlywayAutoConfiguration.class, EndpointAutoConfiguration.class);
this.context.refresh();
FlywayEndpoint endpoint = this.context.getBean(FlywayEndpoint.class);
assertNotNull(endpoint);
assertEquals(1, endpoint.invoke().size());
}
@Test
public void testLiquibaseEndpoint() {
this.context = new AnnotationConfigApplicationContext();
this.context.register(EmbeddedDataSourceConfiguration.class,
LiquibaseAutoConfiguration.class, EndpointAutoConfiguration.class);
this.context.refresh();
LiquibaseEndpoint endpoint = this.context.getBean(LiquibaseEndpoint.class);
assertNotNull(endpoint);
assertEquals(1, endpoint.invoke().size());
}
private void load(Class<?>... config) { private void load(Class<?>... config) {
this.context = new AnnotationConfigApplicationContext(); this.context = new AnnotationConfigApplicationContext();
this.context.register(config); this.context.register(config);

@ -23,11 +23,14 @@ import java.util.Map;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
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.core.env.MapPropertySource; import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource; import org.springframework.core.env.PropertySource;
import com.fasterxml.jackson.databind.ObjectMapper;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@ -41,7 +44,7 @@ public abstract class AbstractEndpointTests<T extends Endpoint<?>> {
protected AnnotationConfigApplicationContext context; protected AnnotationConfigApplicationContext context;
private final Class<?> configClass; protected final Class<?> configClass;
private final Class<?> type; private final Class<?> type;
@ -63,7 +66,7 @@ public abstract class AbstractEndpointTests<T extends Endpoint<?>> {
@Before @Before
public void setup() { public void setup() {
this.context = new AnnotationConfigApplicationContext(); this.context = new AnnotationConfigApplicationContext();
this.context.register(this.configClass); this.context.register(JacksonAutoConfiguration.class, this.configClass);
this.context.refresh(); this.context.refresh();
} }
@ -160,6 +163,14 @@ public abstract class AbstractEndpointTests<T extends Endpoint<?>> {
assertThat(getEndpointBean().isEnabled(), equalTo(true)); assertThat(getEndpointBean().isEnabled(), equalTo(true));
} }
@Test
public void serialize() throws Exception {
Object result = getEndpointBean().invoke();
if (result != null) {
this.context.getBean(ObjectMapper.class).writeValue(System.out, result);
}
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected T getEndpointBean() { protected T getEndpointBean() {
return (T) this.context.getBean(this.type); return (T) this.context.getBean(this.type);

@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionEvaluationRepor
import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -51,6 +52,9 @@ public class AutoConfigurationReportEndpointTests extends
@Test @Test
public void invoke() throws Exception { public void invoke() throws Exception {
this.context = new AnnotationConfigApplicationContext();
this.context.register(this.configClass);
this.context.refresh();
Report report = getEndpointBean().invoke(); Report report = getEndpointBean().invoke();
assertTrue(report.getPositiveMatches().isEmpty()); assertTrue(report.getPositiveMatches().isEmpty());
assertTrue(report.getNegativeMatches().containsKey("a")); assertTrue(report.getNegativeMatches().containsKey("a"));

@ -0,0 +1,61 @@
/*
* 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 org.flywaydb.core.Flyway;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link FlywayEndpoint}.
*
* @author Eddú Meléndez
*/
public class FlywayEndpointTests extends AbstractEndpointTests<FlywayEndpoint> {
public FlywayEndpointTests() {
super(Config.class, FlywayEndpoint.class, "flyway", true, "endpoints.flyway");
}
@Test
public void invoke() throws Exception {
assertThat(getEndpointBean().invoke().size(), is(1));
}
@Configuration
@Import({ EmbeddedDataSourceConfiguration.class, FlywayAutoConfiguration.class })
public static class Config {
@Autowired
private Flyway flyway;
@Bean
public FlywayEndpoint endpoint() {
return new FlywayEndpoint(this.flyway);
}
}
}

@ -0,0 +1,63 @@
/*
* 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 liquibase.integration.spring.SpringLiquibase;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link LiquibaseEndpoint}.
*
* @author Eddú Meléndez
*/
public class LiquibaseEndpointTests extends AbstractEndpointTests<LiquibaseEndpoint> {
public LiquibaseEndpointTests() {
super(Config.class, LiquibaseEndpoint.class, "liquibase", true,
"endpoints.liquibase");
}
@Test
public void invoke() throws Exception {
assertThat(getEndpointBean().invoke().size(), is(1));
}
@Configuration
@Import({ EmbeddedDataSourceConfiguration.class, LiquibaseAutoConfiguration.class })
public static class Config {
@Autowired
private SpringLiquibase liquibase;
@Bean
public LiquibaseEndpoint endpoint() {
return new LiquibaseEndpoint(this.liquibase);
}
}
}

@ -0,0 +1,20 @@
databaseChangeLog:
- changeSet:
id: 1
author: marceloverdijk
changes:
- createTable:
tableName: customer
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: name
type: varchar(50)
constraints:
nullable: false

@ -85,6 +85,10 @@ The following endpoints are available:
|Exposes properties from Spring's `ConfigurableEnvironment`. |Exposes properties from Spring's `ConfigurableEnvironment`.
|true |true
|`flyway`
|Shows any Flyway database migrations that have been applied.
|true
|`health` |`health`
|Shows application health information (when the application is secure, a simple '`status`' when accessed over an |Shows application health information (when the application is secure, a simple '`status`' when accessed over an
unauthenticated connection or full message details when authenticated). unauthenticated connection or full message details when authenticated).
@ -94,6 +98,10 @@ unauthenticated connection or full message details when authenticated).
|Displays arbitrary application info. |Displays arbitrary application info.
|false |false
|`liquibase`
|Shows any Liquibase database migrations that have been applied.
|true
|`logfile` |`logfile`
|Returns the contents of the logfile (if `logging.file` or `logging.path` properties have |Returns the contents of the logfile (if `logging.file` or `logging.path` properties have
been set). Only available via MVC. been set). Only available via MVC.

Loading…
Cancel
Save