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
pull/5489/head
Andy Wilkinson 9 years ago
parent c4205d04b3
commit 617c97322d

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

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

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

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

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

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

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

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

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

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

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

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

@ -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"); * 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.
@ -34,6 +34,9 @@ public abstract class AbstractEndpointMvcAdapter<E extends Endpoint<?>>
private final E delegate; private final E delegate;
/**
* Endpoint URL path.
*/
private String path; private String path;
/** /**

@ -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"); * 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.
@ -40,6 +40,9 @@ public class DocsMvcEndpoint extends WebMvcConfigurerAdapter
private Environment environment; private Environment environment;
/**
* Endpoint URL path.
*/
private String path = "/docs"; private String path = "/docs";
/** /**

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

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

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

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

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

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

@ -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"); * 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.
@ -24,9 +24,13 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; 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.stereotype.Component;
import org.springframework.util.StringUtils;
/** /**
* A registry for all {@link MvcEndpoint} beans, and a factory for a set of generic ones * 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) { for (Endpoint<?> endpoint : delegates) {
if (isGenericEndpoint(endpoint.getClass()) && endpoint.isEnabled()) { if (isGenericEndpoint(endpoint.getClass()) && endpoint.isEnabled()) {
EndpointMvcAdapter adapter = new EndpointMvcAdapter(endpoint); EndpointMvcAdapter adapter = new EndpointMvcAdapter(endpoint);
String path = this.applicationContext.getEnvironment() String path = determinePath(endpoint,
.getProperty("endpoints." + endpoint.getId() + ".path"); this.applicationContext.getEnvironment());
if (path != null) { if (path != null) {
adapter.setPath(path); adapter.setPath(path);
} }
@ -94,4 +98,15 @@ public class MvcEndpoints implements ApplicationContextAware, InitializingBean {
&& !MvcEndpoint.class.isAssignableFrom(type); && !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;
}
} }

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

@ -1,28 +1,63 @@
{"properties": [ {"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", "name": "endpoints.configprops.keys-to-sanitize",
"type": "java.lang.String[]", "type": "java.lang.String[]",
"sourceType": "org.springframework.boot.actuate.endpoint.ConfigurationPropertiesReportEndpoint", "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." "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", "name": "endpoints.env.keys-to-sanitize",
"type": "java.lang.String[]", "type": "java.lang.String[]",
"sourceType": "org.springframework.boot.actuate.endpoint.EnvironmentEndpoint", "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." "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", "name": "endpoints.jmx.enabled",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"description": "Enable JMX export of all endpoints.", "description": "Enable JMX export of all endpoints.",
"defaultValue": true "defaultValue": true
}, },
{
"name": "endpoints.mappings.path",
"type": "java.lang.String",
"description": "Endpoint URL path."
},
{ {
"name": "endpoints.metrics.filter.enabled", "name": "endpoints.metrics.filter.enabled",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"description": "Enable the metrics servlet filter.", "description": "Enable the metrics servlet filter.",
"defaultValue": true "defaultValue": true
}, },
{
"name": "endpoints.trace.path",
"type": "java.lang.String",
"description": "Endpoint URL path."
},
{ {
"name": "info", "name": "info",
"type": "java.util.Map<java.lang.String,java.lang.Object>", "type": "java.util.Map<java.lang.String,java.lang.Object>",

@ -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);
}
}
}

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

Loading…
Cancel
Save