Allow endpoint paths to be configured via endpoint.<name>.path

Support for configuring an endpoint’s path separately from its id was
introduced in 97255785, but it didn’t work for a variety of reasons:

 1. Some custom MVC endpoints did not have configuration properties
    bound to them
 2. Some generic endpoints rejected the path property as they were
    configured not to ignore unknown fields
 3. The property used to configure the path was dependent on the id
    of the endpoint. This meant that the path property’s name would
    change if the endpoint’s id was changed

This commit addresses these problems:

 1. @ConfigurationProperties has been added to custom MvcEndpoints where
    it was missing
 2. Generic endpoints have been updated to ignore unknown fields,
    allowing the path of their MVC adapter to be configured
 3. Rather than using the id of a generic endpoint to determine the name
    of its path property, the prefix or value of the endpoint’s
    @ConfigurationProperties annotation is used instead. Any generic
    endpoint that is not annotated with @ConfigurationProperties is
    ignored, making its path unconfigurable.

Closes gh-5105
This commit is contained in:
Andy Wilkinson 2016-02-22 17:55:27 +00:00
parent c4205d04b3
commit 617c97322d
25 changed files with 277 additions and 38 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -44,7 +44,7 @@ import org.springframework.util.StringUtils;
* @author Dave Syer
* @author Andy Wilkinson
*/
@ConfigurationProperties(prefix = "endpoints.autoconfig", ignoreUnknownFields = false)
@ConfigurationProperties(prefix = "endpoints.autoconfig")
public class AutoConfigurationReportEndpoint extends AbstractEndpoint<Report> {
@Autowired

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -35,7 +35,7 @@ import org.springframework.core.env.Environment;
*
* @author Dave Syer
*/
@ConfigurationProperties(prefix = "endpoints.beans", ignoreUnknownFields = false)
@ConfigurationProperties(prefix = "endpoints.beans")
public class BeansEndpoint extends AbstractEndpoint<List<Object>>
implements ApplicationContextAware {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -58,7 +58,7 @@ import org.springframework.util.StringUtils;
* @author Christian Dupuis
* @author Dave Syer
*/
@ConfigurationProperties(prefix = "endpoints.configprops", ignoreUnknownFields = false)
@ConfigurationProperties(prefix = "endpoints.configprops")
public class ConfigurationPropertiesReportEndpoint
extends AbstractEndpoint<Map<String, Object>> implements ApplicationContextAware {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -28,7 +28,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
*
* @author Dave Syer
*/
@ConfigurationProperties(prefix = "endpoints.dump", ignoreUnknownFields = false)
@ConfigurationProperties(prefix = "endpoints.dump")
public class DumpEndpoint extends AbstractEndpoint<List<ThreadInfo>> {
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -36,7 +36,7 @@ import org.springframework.core.env.StandardEnvironment;
* @author Phillip Webb
* @author Christian Dupuis
*/
@ConfigurationProperties(prefix = "endpoints.env", ignoreUnknownFields = false)
@ConfigurationProperties(prefix = "endpoints.env")
public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> {
private final Sanitizer sanitizer = new Sanitizer();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -36,7 +36,7 @@ import org.springframework.util.Assert;
* @author Phillip Webb
* @since 1.3.0
*/
@ConfigurationProperties(prefix = "endpoints.flyway", ignoreUnknownFields = true)
@ConfigurationProperties(prefix = "endpoints.flyway")
public class FlywayEndpoint extends AbstractEndpoint<List<FlywayMigration>> {
private final Flyway flyway;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -32,7 +32,7 @@ import org.springframework.util.Assert;
* @author Christian Dupuis
* @author Andy Wilkinson
*/
@ConfigurationProperties(prefix = "endpoints.health", ignoreUnknownFields = true)
@ConfigurationProperties(prefix = "endpoints.health")
public class HealthEndpoint extends AbstractEndpoint<Health> {
private final HealthIndicator healthIndicator;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -28,7 +28,7 @@ import org.springframework.util.Assert;
*
* @author Dave Syer
*/
@ConfigurationProperties(prefix = "endpoints.info", ignoreUnknownFields = false)
@ConfigurationProperties(prefix = "endpoints.info")
public class InfoEndpoint extends AbstractEndpoint<Map<String, Object>> {
private final Map<String, ? extends Object> info;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -36,7 +36,7 @@ import org.springframework.util.Assert;
* @author Eddú Meléndez
* @since 1.3.0
*/
@ConfigurationProperties(prefix = "endpoints.liquibase", ignoreUnknownFields = true)
@ConfigurationProperties(prefix = "endpoints.liquibase")
public class LiquibaseEndpoint extends AbstractEndpoint<List<Map<String, ?>>> {
private final SpringLiquibase liquibase;

View File

@ -38,7 +38,7 @@ import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
* @author Dave Syer
* @author Andy Wilkinson
*/
@ConfigurationProperties(prefix = "endpoints.mappings", ignoreUnknownFields = false)
@ConfigurationProperties(prefix = "endpoints.mappings")
public class RequestMappingEndpoint extends AbstractEndpoint<Map<String, Object>>
implements ApplicationContextAware {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -31,7 +31,7 @@ import org.springframework.context.ConfigurableApplicationContext;
* @author Dave Syer
* @author Christian Dupuis
*/
@ConfigurationProperties(prefix = "endpoints.shutdown", ignoreUnknownFields = false)
@ConfigurationProperties(prefix = "endpoints.shutdown")
public class ShutdownEndpoint extends AbstractEndpoint<Map<String, Object>>
implements ApplicationContextAware {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -28,7 +28,7 @@ import org.springframework.util.Assert;
*
* @author Dave Syer
*/
@ConfigurationProperties(prefix = "endpoints.trace", ignoreUnknownFields = false)
@ConfigurationProperties(prefix = "endpoints.trace")
public class TraceEndpoint extends AbstractEndpoint<List<Trace>> {
private final TraceRepository repository;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -34,6 +34,9 @@ public abstract class AbstractEndpointMvcAdapter<E extends Endpoint<?>>
private final E delegate;
/**
* Endpoint URL path.
*/
private String path;
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -40,6 +40,9 @@ public class DocsMvcEndpoint extends WebMvcConfigurerAdapter
private Environment environment;
/**
* Endpoint URL path.
*/
private String path = "/docs";
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -17,6 +17,7 @@
package org.springframework.boot.actuate.endpoint.mvc;
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
@ -38,6 +39,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
* @author Christian Dupuis
* @author Andy Wilkinson
*/
@ConfigurationProperties(prefix = "endpoints.env")
public class EnvironmentMvcEndpoint extends EndpointMvcAdapter
implements EnvironmentAware {

View File

@ -49,7 +49,7 @@ public class HalJsonMvcEndpoint extends WebMvcConfigurerAdapter
* Endpoint URL path.
*/
@NotNull
@Pattern(regexp = "^$|/[^/]*", message = "Path must be empty or start with /")
@Pattern(regexp = "^$|/.*", message = "Path must be empty or start with /")
private String path;
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -25,6 +25,7 @@ import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.bind.RelaxedNames;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
@ -46,6 +47,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @author Phillip Webb
* @since 1.1.0
*/
@ConfigurationProperties(prefix = "endpoints.health")
public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter<HealthEndpoint>
implements EnvironmentAware {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2016 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.
@ -59,8 +59,8 @@ public class JolokiaMvcEndpoint implements MvcEndpoint, InitializingBean,
* Endpoint URL path.
*/
@NotNull
@Pattern(regexp = "/[^?#]*", message = "Path must start with /")
private String path = "/jolokia";;
@Pattern(regexp = "/.*", message = "Path must start with /")
private String path = "/jolokia";
/**
* Enable the endpoint.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -59,7 +59,7 @@ public class LogFileMvcEndpoint implements MvcEndpoint, EnvironmentAware {
* Endpoint URL path.
*/
@NotNull
@Pattern(regexp = "/[^/]*", message = "Path must start with /")
@Pattern(regexp = "/.*", message = "Path must start with /")
private String path = "/logfile";
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.mvc;
import java.util.Map;
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
@ -34,6 +35,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
* @author Andy Wilkinson
* @author Sergei Egorov
*/
@ConfigurationProperties(prefix = "endpoints.metrics")
public class MetricsMvcEndpoint extends EndpointMvcAdapter {
private final MetricsEndpoint delegate;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -24,9 +24,13 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
/**
* A registry for all {@link MvcEndpoint} beans, and a factory for a set of generic ones
@ -64,8 +68,8 @@ public class MvcEndpoints implements ApplicationContextAware, InitializingBean {
for (Endpoint<?> endpoint : delegates) {
if (isGenericEndpoint(endpoint.getClass()) && endpoint.isEnabled()) {
EndpointMvcAdapter adapter = new EndpointMvcAdapter(endpoint);
String path = this.applicationContext.getEnvironment()
.getProperty("endpoints." + endpoint.getId() + ".path");
String path = determinePath(endpoint,
this.applicationContext.getEnvironment());
if (path != null) {
adapter.setPath(path);
}
@ -94,4 +98,15 @@ public class MvcEndpoints implements ApplicationContextAware, InitializingBean {
&& !MvcEndpoint.class.isAssignableFrom(type);
}
private String determinePath(Endpoint<?> endpoint, Environment environment) {
ConfigurationProperties configurationProperties = AnnotationUtils
.findAnnotation(endpoint.getClass(), ConfigurationProperties.class);
if (configurationProperties != null) {
String prefix = StringUtils.hasText(configurationProperties.prefix())
? configurationProperties.prefix() : configurationProperties.value();
return environment.getProperty(prefix + ".path");
}
return null;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.Map;
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
@ -31,6 +32,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
*
* @author Dave Syer
*/
@ConfigurationProperties(prefix = "endpoints.shutdown")
public class ShutdownMvcEndpoint extends EndpointMvcAdapter {
public ShutdownMvcEndpoint(ShutdownEndpoint delegate) {

View File

@ -1,28 +1,63 @@
{"properties": [
{
"name": "endpoints.autoconfig.path",
"type": "java.lang.String",
"description": "Endpoint URL path."
},
{
"name": "endpoints.beans.path",
"type": "java.lang.String",
"description": "Endpoint URL path."
},
{
"name": "endpoints.configprops.keys-to-sanitize",
"type": "java.lang.String[]",
"sourceType": "org.springframework.boot.actuate.endpoint.ConfigurationPropertiesReportEndpoint",
"description": "Keys that should be sanitized. Keys can be simple strings that the property ends with or regex expressions."
},
{
"name": "endpoints.configprops.path",
"type": "java.lang.String",
"description": "Endpoint URL path."
},
{
"name": "endpoints.dump.path",
"type": "java.lang.String",
"description": "Endpoint URL path."
},
{
"name": "endpoints.env.keys-to-sanitize",
"type": "java.lang.String[]",
"sourceType": "org.springframework.boot.actuate.endpoint.EnvironmentEndpoint",
"description": "Keys that should be sanitized. Keys can be simple strings that the property ends with or regex expressions."
},
{
"name": "endpoints.info.path",
"type": "java.lang.String",
"description": "Endpoint URL path."
},
{
"name": "endpoints.jmx.enabled",
"type": "java.lang.Boolean",
"description": "Enable JMX export of all endpoints.",
"defaultValue": true
},
{
"name": "endpoints.mappings.path",
"type": "java.lang.String",
"description": "Endpoint URL path."
},
{
"name": "endpoints.metrics.filter.enabled",
"type": "java.lang.Boolean",
"description": "Enable the metrics servlet filter.",
"defaultValue": true
},
{
"name": "endpoints.trace.path",
"type": "java.lang.String",
"description": "Endpoint URL path."
},
{
"name": "info",
"type": "java.util.Map<java.lang.String,java.lang.Object>",

View File

@ -0,0 +1,173 @@
/*
* Copyright 2012-2016 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.autoconfigure;
import liquibase.integration.spring.SpringLiquibase;
import org.flywaydb.core.Flyway;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint;
import org.springframework.boot.actuate.endpoint.BeansEndpoint;
import org.springframework.boot.actuate.endpoint.ConfigurationPropertiesReportEndpoint;
import org.springframework.boot.actuate.endpoint.DumpEndpoint;
import org.springframework.boot.actuate.endpoint.FlywayEndpoint;
import org.springframework.boot.actuate.endpoint.InfoEndpoint;
import org.springframework.boot.actuate.endpoint.LiquibaseEndpoint;
import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
import org.springframework.boot.actuate.endpoint.TraceEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.DocsMvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
import org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.HalJsonMvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.JolokiaMvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.LogFileMvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.ManagementServletContext;
import org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoints;
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
import org.springframework.boot.autoconfigure.test.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration;
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
/**
* Tests for configuring the path of an MVC endpoint.
*
* @author Andy Wilkinson
*/
@RunWith(Parameterized.class)
public class MvcEndpointPathConfigurationTests {
private final String endpointName;
private final Class<?> endpointClass;
private AnnotationConfigWebApplicationContext context;
@After
public void cleanUp() {
if (this.context != null) {
this.context.close();
}
}
@Parameters(name = "{0}")
public static Object[] parameters() {
return new Object[] { new Object[] { "actuator", HalJsonMvcEndpoint.class },
new Object[] { "autoconfig", AutoConfigurationReportEndpoint.class },
new Object[] { "beans", BeansEndpoint.class },
new Object[] { "configprops",
ConfigurationPropertiesReportEndpoint.class },
new Object[] { "docs", DocsMvcEndpoint.class },
new Object[] { "dump", DumpEndpoint.class },
new Object[] { "env", EnvironmentMvcEndpoint.class },
new Object[] { "flyway", FlywayEndpoint.class },
new Object[] { "health", HealthMvcEndpoint.class },
new Object[] { "info", InfoEndpoint.class },
new Object[] { "jolokia", JolokiaMvcEndpoint.class },
new Object[] { "liquibase", LiquibaseEndpoint.class },
new Object[] { "logfile", LogFileMvcEndpoint.class },
new Object[] { "mappings", RequestMappingEndpoint.class },
new Object[] { "metrics", MetricsMvcEndpoint.class },
new Object[] { "shutdown", ShutdownEndpoint.class },
new Object[] { "trace", TraceEndpoint.class } };
}
public MvcEndpointPathConfigurationTests(String endpointName,
Class<?> endpointClass) {
this.endpointName = endpointName;
this.endpointClass = endpointClass;
}
@Test
public void pathCanBeConfigured() {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(TestConfiguration.class);
this.context.setServletContext(new MockServletContext());
EnvironmentTestUtils.addEnvironment(this.context,
"endpoints." + this.endpointName + ".path" + ":/custom/path",
"endpoints." + this.endpointName + ".enabled:true",
"logging.file:target/test.log");
this.context.refresh();
assertThat(getConfiguredPath(), is(equalTo("/custom/path")));
}
private String getConfiguredPath() {
if (MvcEndpoint.class.isAssignableFrom(this.endpointClass)) {
return ((MvcEndpoint) this.context.getBean(this.endpointClass)).getPath();
}
for (MvcEndpoint endpoint : this.context.getBean(MvcEndpoints.class)
.getEndpoints()) {
if (endpoint instanceof EndpointMvcAdapter && this.endpointClass
.isInstance(((EndpointMvcAdapter) endpoint).getDelegate())) {
return ((EndpointMvcAdapter) endpoint).getPath();
}
}
throw new IllegalStateException(
"Could not get configured path for " + this.endpointClass);
}
@Configuration
@ImportAutoConfiguration({ EndpointAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class,
ServerPropertiesAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class,
EndpointAutoConfiguration.class })
protected static class TestConfiguration {
@Bean
public ConditionEvaluationReport conditionEvaluationReport(
ConfigurableListableBeanFactory beanFactory) {
return ConditionEvaluationReport.get(beanFactory);
}
@Bean
public FlywayEndpoint flyway() {
return new FlywayEndpoint(new Flyway());
}
@Bean
public LiquibaseEndpoint liquibase() {
return new LiquibaseEndpoint(new SpringLiquibase());
}
@Bean
public DocsMvcEndpoint docs(ManagementServletContext managementServletContext) {
return new DocsMvcEndpoint(managementServletContext);
}
}
}

View File

@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.mvc;
import org.junit.Test;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.support.StaticApplicationContext;
@ -77,6 +78,7 @@ public class MvcEndpointsTests {
this.endpoints.getEndpoints().iterator().next().getPath());
}
@ConfigurationProperties("endpoints.test")
protected static class TestEndpoint extends AbstractEndpoint<String> {
public TestEndpoint() {