@FrameworkEndpoint replaces EndpointHandlerAdapter
This commit is contained in:
@@ -29,7 +29,6 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerAdapter;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;
|
||||
import org.springframework.boot.actuate.properties.ManagementServerProperties;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
@@ -40,7 +39,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
||||
@@ -91,15 +89,6 @@ public class EndpointWebMvcAutoConfiguration implements ApplicationContextAware,
|
||||
return mapping;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public EndpointHandlerAdapter endpointHandlerAdapter(
|
||||
final HttpMessageConverters messageConverters) {
|
||||
EndpointHandlerAdapter adapter = new EndpointHandlerAdapter();
|
||||
adapter.setMessageConverters(messageConverters.getConverters());
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
@@ -26,9 +24,7 @@ import org.springframework.beans.factory.HierarchicalBeanFactory;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerAdapter;
|
||||
import org.springframework.boot.actuate.endpoint.ManagementErrorEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;
|
||||
import org.springframework.boot.actuate.properties.ManagementServerProperties;
|
||||
import org.springframework.boot.actuate.web.ErrorController;
|
||||
@@ -42,11 +38,11 @@ import org.springframework.boot.context.embedded.ErrorPage;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
|
||||
/**
|
||||
* Configuration triggered from {@link EndpointWebMvcAutoConfiguration} when a new
|
||||
@@ -57,6 +53,9 @@ import org.springframework.web.servlet.HandlerMapping;
|
||||
@Configuration
|
||||
public class EndpointWebMvcChildContextConfiguration {
|
||||
|
||||
@Value("${error.path:/error}")
|
||||
private String errorPath = "/error";
|
||||
|
||||
@Configuration
|
||||
protected static class ServerCustomization implements
|
||||
EmbeddedServletContainerCustomizer {
|
||||
@@ -100,13 +99,19 @@ public class EndpointWebMvcChildContextConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HandlerMapping handlerMapping() {
|
||||
return new EndpointHandlerMapping();
|
||||
public HandlerAdapter handlerAdapter() {
|
||||
// TODO: maybe this needs more configuration for non-basic response use cases
|
||||
RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
|
||||
adapter.setMessageConverters(new RestTemplate().getMessageConverters());
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HandlerAdapter handlerAdapter() {
|
||||
return new EndpointHandlerAdapter();
|
||||
public HandlerMapping handlerMapping() {
|
||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping();
|
||||
// In a child context we definitely want to see the parent endpoints
|
||||
mapping.setDetectHandlerMethodsInAncestorContexts(true);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -116,15 +121,8 @@ public class EndpointWebMvcChildContextConfiguration {
|
||||
* endpoints.
|
||||
*/
|
||||
@Bean
|
||||
public Endpoint<Map<String, Object>> errorEndpoint(final ErrorController controller) {
|
||||
return new AbstractEndpoint<Map<String, Object>>("/error", false, true) {
|
||||
@Override
|
||||
protected Map<String, Object> doInvoke() {
|
||||
RequestAttributes attributes = RequestContextHolder
|
||||
.currentRequestAttributes();
|
||||
return controller.extract(attributes, false);
|
||||
}
|
||||
};
|
||||
public ManagementErrorEndpoint errorEndpoint(final ErrorController controller) {
|
||||
return new ManagementErrorEndpoint(this.errorPath, controller);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
||||
@@ -19,28 +19,15 @@ package org.springframework.boot.actuate.endpoint;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Pattern;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* Abstract base for {@link Endpoint} implementations.
|
||||
* <p>
|
||||
* {@link Endpoint}s that support other {@link HttpMethod}s than {@link HttpMethod#GET}
|
||||
* should override {@link #methods()} and provide a list of supported methods.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
public abstract class AbstractEndpoint<T> implements Endpoint<T> {
|
||||
|
||||
private static final MediaType[] NO_MEDIA_TYPES = new MediaType[0];
|
||||
|
||||
protected static final HttpMethod[] NO_HTTP_METHOD = new HttpMethod[0];
|
||||
|
||||
protected static final HttpMethod[] GET_HTTP_METHOD = new HttpMethod[] { HttpMethod.GET };
|
||||
|
||||
protected static final HttpMethod[] POST_HTTP_METHOD = new HttpMethod[] { HttpMethod.POST };
|
||||
|
||||
@NotNull
|
||||
@Pattern(regexp = "/[^/]*", message = "Path must start with /")
|
||||
private String path;
|
||||
@@ -85,23 +72,4 @@ public abstract class AbstractEndpoint<T> implements Endpoint<T> {
|
||||
this.sensitive = sensitive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaType[] produces() {
|
||||
return NO_MEDIA_TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpMethod[] methods() {
|
||||
return GET_HTTP_METHOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final T invoke() {
|
||||
if (this.enabled) {
|
||||
return doInvoke();
|
||||
}
|
||||
throw new EndpointDisabledException();
|
||||
}
|
||||
|
||||
protected abstract T doInvoke();
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.AutoConfigurationReportEndpoint.Report;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationReport;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationReport.ConditionAndOutcome;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurationReport.ConditionAndOutcomes;
|
||||
@@ -31,6 +32,8 @@ import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
|
||||
@@ -42,6 +45,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConfigurationProperties(name = "endpoints.autoconfig", ignoreUnknownFields = false)
|
||||
@FrameworkEndpoint
|
||||
public class AutoConfigurationReportEndpoint extends AbstractEndpoint<Report> {
|
||||
|
||||
@Autowired
|
||||
@@ -52,7 +56,9 @@ public class AutoConfigurationReportEndpoint extends AbstractEndpoint<Report> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Report doInvoke() {
|
||||
@RequestMapping
|
||||
@ResponseBody
|
||||
public Report invoke() {
|
||||
return new Report(this.autoConfigurationReport);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,12 +17,15 @@
|
||||
package org.springframework.boot.actuate.endpoint;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.support.LiveBeansView;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* Exposes JSON view of Spring beans. If the {@link Environment} contains a key setting
|
||||
@@ -33,6 +36,7 @@ import org.springframework.http.MediaType;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConfigurationProperties(name = "endpoints.beans", ignoreUnknownFields = false)
|
||||
@FrameworkEndpoint
|
||||
public class BeansEndpoint extends AbstractEndpoint<String> implements
|
||||
ApplicationContextAware {
|
||||
|
||||
@@ -51,12 +55,9 @@ public class BeansEndpoint extends AbstractEndpoint<String> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaType[] produces() {
|
||||
return new MediaType[] { MediaType.APPLICATION_JSON };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInvoke() {
|
||||
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public String invoke() {
|
||||
return this.liveBeansView.getSnapshotAsJson();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,13 @@ package org.springframework.boot.actuate.endpoint;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@@ -37,6 +40,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
@ConfigurationProperties(name = "endpoints.configprops", ignoreUnknownFields = false)
|
||||
@FrameworkEndpoint
|
||||
public class ConfigurationPropertiesReportEndpoint extends
|
||||
AbstractEndpoint<Map<String, Object>> implements ApplicationContextAware {
|
||||
|
||||
@@ -64,7 +68,9 @@ public class ConfigurationPropertiesReportEndpoint extends
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<String, Object> doInvoke() {
|
||||
@RequestMapping
|
||||
@ResponseBody
|
||||
public Map<String, Object> invoke() {
|
||||
Map<String, Object> beans = this.context
|
||||
.getBeansWithAnnotation(ConfigurationProperties.class);
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@ import java.lang.management.ThreadInfo;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* {@link Endpoint} to expose thread info.
|
||||
@@ -29,6 +32,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConfigurationProperties(name = "endpoints.dump", ignoreUnknownFields = false)
|
||||
@FrameworkEndpoint
|
||||
public class DumpEndpoint extends AbstractEndpoint<List<ThreadInfo>> {
|
||||
|
||||
/**
|
||||
@@ -39,7 +43,9 @@ public class DumpEndpoint extends AbstractEndpoint<List<ThreadInfo>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ThreadInfo> doInvoke() {
|
||||
@RequestMapping
|
||||
@ResponseBody
|
||||
public List<ThreadInfo> invoke() {
|
||||
return Arrays.asList(ManagementFactory.getThreadMXBean().dumpAllThreads(true,
|
||||
true));
|
||||
}
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
package org.springframework.boot.actuate.endpoint;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* An endpoint that can be used to expose useful information to operations. Usually
|
||||
* exposed via Spring MVC but could also be exposed using some other technique.
|
||||
@@ -41,16 +38,6 @@ public interface Endpoint<T> {
|
||||
*/
|
||||
boolean isSensitive();
|
||||
|
||||
/**
|
||||
* Returns the {@link MediaType}s that this endpoint produces or {@code null}.
|
||||
*/
|
||||
MediaType[] produces();
|
||||
|
||||
/**
|
||||
* Returns the {@link HttpMethod}s that this endpoint supports.
|
||||
*/
|
||||
HttpMethod[] methods();
|
||||
|
||||
/**
|
||||
* Called to invoke the endpoint.
|
||||
* @return the results of the invocation
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
@@ -26,6 +27,11 @@ import org.springframework.core.env.EnumerablePropertySource;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
/**
|
||||
* {@link Endpoint} to expose {@link ConfigurableEnvironment environment} information.
|
||||
@@ -34,6 +40,7 @@ import org.springframework.core.env.StandardEnvironment;
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@ConfigurationProperties(name = "endpoints.env", ignoreUnknownFields = false)
|
||||
@FrameworkEndpoint
|
||||
public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> implements
|
||||
EnvironmentAware {
|
||||
|
||||
@@ -47,7 +54,9 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> i
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> doInvoke() {
|
||||
@RequestMapping
|
||||
@ResponseBody
|
||||
public Map<String, Object> invoke() {
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
||||
result.put("profiles", this.environment.getActiveProfiles());
|
||||
for (PropertySource<?> source : getPropertySources()) {
|
||||
@@ -63,6 +72,16 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> i
|
||||
return result;
|
||||
}
|
||||
|
||||
@RequestMapping("/{name:.*}")
|
||||
@ResponseBody
|
||||
public Object value(@PathVariable String name) {
|
||||
String result = this.environment.getProperty(name);
|
||||
if (result == null) {
|
||||
throw new NoSuchPropertyException("No such property: " + name);
|
||||
}
|
||||
return sanitize(name, result);
|
||||
}
|
||||
|
||||
private Iterable<PropertySource<?>> getPropertySources() {
|
||||
if (this.environment != null
|
||||
&& this.environment instanceof ConfigurableEnvironment) {
|
||||
@@ -84,4 +103,13 @@ public class EnvironmentEndpoint extends AbstractEndpoint<Map<String, Object>> i
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "No such property")
|
||||
public static class NoSuchPropertyException extends RuntimeException {
|
||||
|
||||
public NoSuchPropertyException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
|
||||
package org.springframework.boot.actuate.endpoint;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* {@link Endpoint} to expose application health.
|
||||
@@ -26,6 +29,7 @@ import org.springframework.util.Assert;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConfigurationProperties(name = "endpoints.health", ignoreUnknownFields = false)
|
||||
@FrameworkEndpoint
|
||||
public class HealthEndpoint<T> extends AbstractEndpoint<T> {
|
||||
|
||||
private HealthIndicator<? extends T> indicator;
|
||||
@@ -41,8 +45,14 @@ public class HealthEndpoint<T> extends AbstractEndpoint<T> {
|
||||
this.indicator = indicator;
|
||||
}
|
||||
|
||||
HealthEndpoint() {
|
||||
super("/health", false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T doInvoke() {
|
||||
@RequestMapping
|
||||
@ResponseBody
|
||||
public T invoke() {
|
||||
return this.indicator.health();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,11 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* {@link Endpoint} to expose arbitrary application information.
|
||||
@@ -29,6 +32,7 @@ import org.springframework.util.Assert;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConfigurationProperties(name = "endpoints.info", ignoreUnknownFields = false)
|
||||
@FrameworkEndpoint
|
||||
public class InfoEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
||||
|
||||
private Map<String, ? extends Object> info;
|
||||
@@ -45,7 +49,9 @@ public class InfoEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> doInvoke() {
|
||||
@RequestMapping
|
||||
@ResponseBody
|
||||
public Map<String, Object> invoke() {
|
||||
Map<String, Object> info = new LinkedHashMap<String, Object>(this.info);
|
||||
info.putAll(getAdditionalInfo());
|
||||
return info;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.boot.actuate.endpoint;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
/**
|
||||
* {@link Endpoint} implementation to register the Jolokia infrastructure with the Boot
|
||||
@@ -33,13 +32,8 @@ public class JolokiaEndpoint extends AbstractEndpoint<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInvoke() {
|
||||
public String invoke() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpMethod[] methods() {
|
||||
return NO_HTTP_METHOD;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.Map;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.actuate.web.ErrorController;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* Special endpoint for handling "/error" path when the management servlet is in a child
|
||||
* context. The regular {@link ErrorController} should be available there but because of
|
||||
* the way the handler mappings are set up it will not be detected.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@FrameworkEndpoint
|
||||
@ConfigurationProperties(name = "error")
|
||||
public class ManagementErrorEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
||||
|
||||
private final ErrorController controller;
|
||||
|
||||
public ManagementErrorEndpoint(String path, ErrorController controller) {
|
||||
super(path, false, true);
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
@RequestMapping
|
||||
@ResponseBody
|
||||
public Map<String, Object> invoke() {
|
||||
RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
|
||||
return this.controller.extract(attributes, false);
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,15 @@ package org.springframework.boot.actuate.endpoint;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
/**
|
||||
* {@link Endpoint} to expose {@link PublicMetrics}.
|
||||
@@ -29,6 +35,7 @@ import org.springframework.util.Assert;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConfigurationProperties(name = "endpoints.metrics", ignoreUnknownFields = false)
|
||||
@FrameworkEndpoint
|
||||
public class MetricsEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
||||
|
||||
private PublicMetrics metrics;
|
||||
@@ -45,7 +52,9 @@ public class MetricsEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> doInvoke() {
|
||||
@RequestMapping
|
||||
@ResponseBody
|
||||
public Map<String, Object> invoke() {
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
||||
for (Metric metric : this.metrics.metrics()) {
|
||||
result.put(metric.getName(), metric.getValue());
|
||||
@@ -53,4 +62,22 @@ public class MetricsEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
||||
return result;
|
||||
}
|
||||
|
||||
@RequestMapping("/{name:.*}")
|
||||
@ResponseBody
|
||||
public Object value(@PathVariable String name) {
|
||||
Object value = invoke().get(name);
|
||||
if (value == null) {
|
||||
throw new NoSuchMetricException("No such metric: " + name);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "No such metric")
|
||||
public static class NoSuchMetricException extends RuntimeException {
|
||||
|
||||
public NoSuchMetricException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,14 @@ import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* {@link Endpoint} to shutdown the {@link ApplicationContext}.
|
||||
@@ -33,6 +36,7 @@ import org.springframework.http.HttpMethod;
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
@ConfigurationProperties(name = "endpoints.shutdown", ignoreUnknownFields = false)
|
||||
@FrameworkEndpoint
|
||||
public class ShutdownEndpoint extends AbstractEndpoint<Map<String, Object>> implements
|
||||
ApplicationContextAware {
|
||||
|
||||
@@ -46,7 +50,9 @@ public class ShutdownEndpoint extends AbstractEndpoint<Map<String, Object>> impl
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> doInvoke() {
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
@ResponseBody
|
||||
public Map<String, Object> invoke() {
|
||||
|
||||
if (this.context == null) {
|
||||
return Collections.<String, Object> singletonMap("message",
|
||||
@@ -77,9 +83,4 @@ public class ShutdownEndpoint extends AbstractEndpoint<Map<String, Object>> impl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpMethod[] methods() {
|
||||
return POST_HTTP_METHOD;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,10 +18,13 @@ package org.springframework.boot.actuate.endpoint;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.actuate.trace.Trace;
|
||||
import org.springframework.boot.actuate.trace.TraceRepository;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* {@link Endpoint} to expose {@link Trace} information.
|
||||
@@ -29,6 +32,7 @@ import org.springframework.util.Assert;
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConfigurationProperties(name = "endpoints.trace", ignoreUnknownFields = false)
|
||||
@FrameworkEndpoint
|
||||
public class TraceEndpoint extends AbstractEndpoint<List<Trace>> {
|
||||
|
||||
private TraceRepository repository;
|
||||
@@ -45,7 +49,9 @@ public class TraceEndpoint extends AbstractEndpoint<List<Trace>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Trace> doInvoke() {
|
||||
@RequestMapping
|
||||
@ResponseBody
|
||||
public List<Trace> invoke() {
|
||||
return this.repository.findAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.mvc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.EndpointDisabledException;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.server.ServletServerHttpResponse;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor;
|
||||
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;
|
||||
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
|
||||
/**
|
||||
* MVC {@link HandlerAdapter} for {@link Endpoint}s. Similar in may respects to
|
||||
* {@link AbstractMessageConverterMethodProcessor} but not tied to annotated methods.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*
|
||||
* @see EndpointHandlerMapping
|
||||
*/
|
||||
public final class EndpointHandlerAdapter implements HandlerAdapter {
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private static final MediaType MEDIA_TYPE_APPLICATION = new MediaType("application");
|
||||
|
||||
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
|
||||
|
||||
private List<HttpMessageConverter<?>> messageConverters;
|
||||
|
||||
private List<MediaType> allSupportedMediaTypes;
|
||||
|
||||
public EndpointHandlerAdapter() {
|
||||
WebMvcConfigurationSupportConventions conventions = new WebMvcConfigurationSupportConventions();
|
||||
setMessageConverters(conventions.getDefaultHttpMessageConverters());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Object handler) {
|
||||
return handler instanceof Endpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastModified(HttpServletRequest request, Object handler) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response,
|
||||
Object handler) throws Exception {
|
||||
handle(request, response, (Endpoint<?>) handler);
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void handle(HttpServletRequest request, HttpServletResponse response,
|
||||
Endpoint<?> endpoint) throws Exception {
|
||||
|
||||
Object result = null;
|
||||
try {
|
||||
result = endpoint.invoke();
|
||||
}
|
||||
catch (EndpointDisabledException e) {
|
||||
// Disabled endpoints should get mapped to a HTTP 404
|
||||
throw new NoSuchRequestHandlingMethodException(request);
|
||||
}
|
||||
|
||||
Class<?> resultClass = result.getClass();
|
||||
|
||||
List<MediaType> mediaTypes = getMediaTypes(request, endpoint, resultClass);
|
||||
MediaType selectedMediaType = selectMediaType(mediaTypes);
|
||||
|
||||
ServletServerHttpResponse outputMessage = new ServletServerHttpResponse(response);
|
||||
try {
|
||||
if (selectedMediaType != null) {
|
||||
selectedMediaType = selectedMediaType.removeQualityValue();
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
|
||||
if (messageConverter.canWrite(resultClass, selectedMediaType)) {
|
||||
((HttpMessageConverter<Object>) messageConverter).write(result,
|
||||
selectedMediaType, outputMessage);
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Written [" + result + "] as \""
|
||||
+ selectedMediaType + "\" using [" + messageConverter
|
||||
+ "]");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new HttpMediaTypeNotAcceptableException(this.allSupportedMediaTypes);
|
||||
}
|
||||
finally {
|
||||
outputMessage.close();
|
||||
}
|
||||
}
|
||||
|
||||
private List<MediaType> getMediaTypes(HttpServletRequest request,
|
||||
Endpoint<?> endpoint, Class<?> resultClass)
|
||||
throws HttpMediaTypeNotAcceptableException {
|
||||
List<MediaType> requested = getAcceptableMediaTypes(request);
|
||||
List<MediaType> producible = getProducibleMediaTypes(endpoint, resultClass);
|
||||
|
||||
Set<MediaType> compatible = new LinkedHashSet<MediaType>();
|
||||
for (MediaType r : requested) {
|
||||
for (MediaType p : producible) {
|
||||
if (r.isCompatibleWith(p)) {
|
||||
compatible.add(getMostSpecificMediaType(r, p));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (compatible.isEmpty()) {
|
||||
throw new HttpMediaTypeNotAcceptableException(producible);
|
||||
}
|
||||
List<MediaType> mediaTypes = new ArrayList<MediaType>(compatible);
|
||||
MediaType.sortBySpecificityAndQuality(mediaTypes);
|
||||
return mediaTypes;
|
||||
}
|
||||
|
||||
private List<MediaType> getAcceptableMediaTypes(HttpServletRequest request)
|
||||
throws HttpMediaTypeNotAcceptableException {
|
||||
List<MediaType> mediaTypes = this.contentNegotiationManager
|
||||
.resolveMediaTypes(new ServletWebRequest(request));
|
||||
return mediaTypes.isEmpty() ? Collections.singletonList(MediaType.ALL)
|
||||
: mediaTypes;
|
||||
}
|
||||
|
||||
private List<MediaType> getProducibleMediaTypes(Endpoint<?> endpoint,
|
||||
Class<?> returnValueClass) {
|
||||
MediaType[] mediaTypes = endpoint.produces();
|
||||
if (mediaTypes != null && mediaTypes.length != 0) {
|
||||
return Arrays.asList(mediaTypes);
|
||||
}
|
||||
|
||||
if (this.allSupportedMediaTypes.isEmpty()) {
|
||||
return Collections.singletonList(MediaType.ALL);
|
||||
}
|
||||
|
||||
List<MediaType> result = new ArrayList<MediaType>();
|
||||
for (HttpMessageConverter<?> converter : this.messageConverters) {
|
||||
if (converter.canWrite(returnValueClass, null)) {
|
||||
result.addAll(converter.getSupportedMediaTypes());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private MediaType getMostSpecificMediaType(MediaType acceptType, MediaType produceType) {
|
||||
produceType = produceType.copyQualityValue(acceptType);
|
||||
return MediaType.SPECIFICITY_COMPARATOR.compare(acceptType, produceType) <= 0 ? acceptType
|
||||
: produceType;
|
||||
}
|
||||
|
||||
private MediaType selectMediaType(List<MediaType> mediaTypes) {
|
||||
MediaType selectedMediaType = null;
|
||||
for (MediaType mediaType : mediaTypes) {
|
||||
if (mediaType.isConcrete()) {
|
||||
selectedMediaType = mediaType;
|
||||
break;
|
||||
}
|
||||
else if (mediaType.equals(MediaType.ALL)
|
||||
|| mediaType.equals(MEDIA_TYPE_APPLICATION)) {
|
||||
selectedMediaType = MediaType.APPLICATION_OCTET_STREAM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return selectedMediaType;
|
||||
}
|
||||
|
||||
public void setContentNegotiationManager(
|
||||
ContentNegotiationManager contentNegotiationManager) {
|
||||
this.contentNegotiationManager = contentNegotiationManager;
|
||||
}
|
||||
|
||||
public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
|
||||
this.messageConverters = messageConverters;
|
||||
Set<MediaType> allSupportedMediaTypes = new LinkedHashSet<MediaType>();
|
||||
for (HttpMessageConverter<?> messageConverter : messageConverters) {
|
||||
allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
|
||||
}
|
||||
this.allSupportedMediaTypes = new ArrayList<MediaType>(allSupportedMediaTypes);
|
||||
MediaType.sortBySpecificity(this.allSupportedMediaTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default conventions, taken from {@link WebMvcConfigurationSupport} with a few minor
|
||||
* tweaks.
|
||||
*/
|
||||
private static class WebMvcConfigurationSupportConventions extends
|
||||
WebMvcConfigurationSupport {
|
||||
public List<HttpMessageConverter<?>> getDefaultHttpMessageConverters() {
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
|
||||
addDefaultHttpMessageConverters(converters);
|
||||
for (HttpMessageConverter<?> converter : converters) {
|
||||
if (converter instanceof MappingJackson2HttpMessageConverter) {
|
||||
MappingJackson2HttpMessageConverter jacksonConverter = (MappingJackson2HttpMessageConverter) converter;
|
||||
jacksonConverter.getObjectMapper().disable(
|
||||
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
}
|
||||
}
|
||||
return converters;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,33 +16,46 @@
|
||||
|
||||
package org.springframework.boot.actuate.endpoint.mvc;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
|
||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
|
||||
/**
|
||||
* {@link HandlerMapping} to map {@link Endpoint}s to URLs via {@link Endpoint#getPath()}.
|
||||
* Only endpoints that are annotated as <code>@FrameworkEndpoint</code> will be mapped,
|
||||
* and within that class only those methods with <code>@RequestMapping</code> will be
|
||||
* exposed. The semantics of <code>@RequestMapping</code> should be identical to a normal
|
||||
* <code>@Controller</code>, but the endpoints should not be annotated as
|
||||
* <code>@Controller</code> (otherwise they will be mapped by the normal MVC mechanisms).
|
||||
*
|
||||
* <p>
|
||||
* One of the aims of the mapping is to support endpoints that work as HTTP endpoints but
|
||||
* can still provide useful service interfaces when there is no HTTP server (and no Spring
|
||||
* MVC on the classpath). Note that any endpoints having method signaturess will break in
|
||||
* a non-servlet environment.
|
||||
* </p>
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Christian Dupuis
|
||||
* @see EndpointHandlerAdapter
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class EndpointHandlerMapping extends AbstractUrlHandlerMapping implements
|
||||
public class EndpointHandlerMapping extends RequestMappingHandlerMapping implements
|
||||
InitializingBean, ApplicationContextAware {
|
||||
|
||||
private List<Endpoint<?>> endpoints;
|
||||
@@ -56,28 +69,16 @@ public class EndpointHandlerMapping extends AbstractUrlHandlerMapping implements
|
||||
* detected from the {@link ApplicationContext}.
|
||||
*/
|
||||
public EndpointHandlerMapping() {
|
||||
setOrder(HIGHEST_PRECEDENCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link EndpointHandlerMapping} with the specified endpoints.
|
||||
* @param endpoints the endpoints
|
||||
*/
|
||||
public EndpointHandlerMapping(Collection<? extends Endpoint<?>> endpoints) {
|
||||
Assert.notNull(endpoints, "Endpoints must not be null");
|
||||
this.endpoints = new ArrayList<Endpoint<?>>(endpoints);
|
||||
// By default the static resource handler mapping is LOWEST_PRECEDENCE - 1
|
||||
setOrder(LOWEST_PRECEDENCE - 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
public void afterPropertiesSet() {
|
||||
super.afterPropertiesSet();
|
||||
if (this.endpoints == null) {
|
||||
this.endpoints = findEndpointBeans();
|
||||
}
|
||||
if (!this.disabled) {
|
||||
for (Endpoint<?> endpoint : this.endpoints) {
|
||||
registerHandler(this.prefix + endpoint.getPath(), endpoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@@ -86,20 +87,60 @@ public class EndpointHandlerMapping extends AbstractUrlHandlerMapping implements
|
||||
getApplicationContext(), Endpoint.class).values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects @FrameworkEndpoint annotations in handler beans.
|
||||
*
|
||||
* @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#isHandler(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
protected Object lookupHandler(String urlPath, HttpServletRequest request)
|
||||
throws Exception {
|
||||
Object handler = super.lookupHandler(urlPath, request);
|
||||
if (handler != null) {
|
||||
Object endpoint = (handler instanceof HandlerExecutionChain ? ((HandlerExecutionChain) handler)
|
||||
.getHandler() : handler);
|
||||
HttpMethod method = HttpMethod.valueOf(request.getMethod());
|
||||
if (endpoint instanceof Endpoint
|
||||
&& supportsMethod(((Endpoint<?>) endpoint).methods(), method)) {
|
||||
return endpoint;
|
||||
protected boolean isHandler(Class<?> beanType) {
|
||||
if (this.disabled) {
|
||||
return false;
|
||||
}
|
||||
return AnnotationUtils.findAnnotation(beanType, FrameworkEndpoint.class) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerHandlerMethod(Object handler, Method method,
|
||||
RequestMappingInfo mapping) {
|
||||
|
||||
if (mapping == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> defaultPatterns = mapping.getPatternsCondition().getPatterns();
|
||||
String[] patterns = new String[defaultPatterns.isEmpty() ? 1 : defaultPatterns
|
||||
.size()];
|
||||
|
||||
String path = "";
|
||||
Object bean = handler;
|
||||
if (bean instanceof String) {
|
||||
bean = getApplicationContext().getBean((String) handler);
|
||||
}
|
||||
if (bean instanceof Endpoint) {
|
||||
Endpoint<?> endpoint = (Endpoint<?>) bean;
|
||||
path = endpoint.getPath();
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
String prefix = StringUtils.hasText(this.prefix) ? this.prefix + path : path;
|
||||
if (defaultPatterns.isEmpty()) {
|
||||
patterns[0] = prefix;
|
||||
}
|
||||
else {
|
||||
for (String pattern : defaultPatterns) {
|
||||
patterns[i] = prefix + pattern;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
PatternsRequestCondition patternsInfo = new PatternsRequestCondition(patterns);
|
||||
|
||||
RequestMappingInfo modified = new RequestMappingInfo(patternsInfo,
|
||||
mapping.getMethodsCondition(), mapping.getParamsCondition(),
|
||||
mapping.getHeadersCondition(), mapping.getConsumesCondition(),
|
||||
mapping.getProducesCondition(), mapping.getCustomCondition());
|
||||
|
||||
super.registerHandlerMethod(handler, method, modified);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,16 +172,4 @@ public class EndpointHandlerMapping extends AbstractUrlHandlerMapping implements
|
||||
public List<Endpoint<?>> getEndpoints() {
|
||||
return Collections.unmodifiableList(this.endpoints);
|
||||
}
|
||||
|
||||
private boolean supportsMethod(HttpMethod[] supportedMethods,
|
||||
HttpMethod requestedMethod) {
|
||||
Assert.notNull(supportedMethods, "SupportMethods must not be null");
|
||||
Assert.notNull(supportedMethods, "RequestedMethod must not be null");
|
||||
for (HttpMethod supportedMethod : supportedMethods) {
|
||||
if (supportedMethod.equals(requestedMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.mvc;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Component
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface FrameworkEndpoint {
|
||||
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class BasicErrorController implements ErrorController {
|
||||
|
||||
@RequestMapping(value = "${error.path:/error}", produces = "text/html")
|
||||
public ModelAndView errorHtml(HttpServletRequest request) {
|
||||
Map<String, Object> map = extract(new ServletRequestAttributes(request), false);
|
||||
Map<String, Object> map = error(request);
|
||||
return new ModelAndView(ERROR_KEY, map);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.TestUtils;
|
||||
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.FrameworkEndpoint;
|
||||
import org.springframework.boot.actuate.properties.ManagementServerProperties;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration;
|
||||
@@ -200,13 +200,8 @@ public class EndpointWebMvcAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Endpoint<String> testEndpoint() {
|
||||
return new AbstractEndpoint<String>("/endpoint", false, true) {
|
||||
@Override
|
||||
public String doInvoke() {
|
||||
return "endpointoutput";
|
||||
}
|
||||
};
|
||||
public TestEndpoint testEndpoint() {
|
||||
return new TestEndpoint();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,4 +240,20 @@ public class EndpointWebMvcAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@FrameworkEndpoint
|
||||
public static class TestEndpoint extends AbstractEndpoint<String> {
|
||||
|
||||
public TestEndpoint() {
|
||||
super("/endpoint", false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@RequestMapping
|
||||
@ResponseBody
|
||||
public String invoke() {
|
||||
return "endpointoutput";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.springframework.boot.TestUtils;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -49,16 +48,13 @@ public abstract class AbstractEndpointTests<T extends Endpoint<?>> {
|
||||
|
||||
private final String property;
|
||||
|
||||
private MediaType[] produces;
|
||||
|
||||
public AbstractEndpointTests(Class<?> configClass, Class<?> type, String path,
|
||||
boolean sensitive, String property, MediaType... produces) {
|
||||
boolean sensitive, String property) {
|
||||
this.configClass = configClass;
|
||||
this.type = type;
|
||||
this.path = path;
|
||||
this.sensitive = sensitive;
|
||||
this.property = property;
|
||||
this.produces = produces;
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -75,11 +71,6 @@ public abstract class AbstractEndpointTests<T extends Endpoint<?>> {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void producesMediaType() {
|
||||
assertThat(getEndpointBean().produces(), equalTo(this.produces));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPath() throws Exception {
|
||||
assertThat(getEndpointBean().getPath(), equalTo(this.path));
|
||||
|
||||
@@ -17,11 +17,9 @@
|
||||
package org.springframework.boot.actuate.endpoint;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.endpoint.BeansEndpoint;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -34,8 +32,7 @@ import static org.junit.Assert.assertThat;
|
||||
public class BeansEndpointTests extends AbstractEndpointTests<BeansEndpoint> {
|
||||
|
||||
public BeansEndpointTests() {
|
||||
super(Config.class, BeansEndpoint.class, "/beans", true, "endpoints.beans",
|
||||
MediaType.APPLICATION_JSON);
|
||||
super(Config.class, BeansEndpoint.class, "/beans", true, "endpoints.beans");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.mvc;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link EndpointHandlerAdapter}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class EndpointHandlerAdapterTests {
|
||||
|
||||
private EndpointHandlerAdapter adapter = new EndpointHandlerAdapter();
|
||||
private MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
private MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
@Test
|
||||
public void onlySupportsEndpoints() throws Exception {
|
||||
assertTrue(this.adapter.supports(mock(Endpoint.class)));
|
||||
assertFalse(this.adapter.supports(mock(Object.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersJson() throws Exception {
|
||||
this.adapter.handle(this.request, this.response,
|
||||
new AbstractEndpoint<Map<String, String>>("/foo") {
|
||||
@Override
|
||||
protected Map<String, String> doInvoke() {
|
||||
return Collections.singletonMap("hello", "world");
|
||||
}
|
||||
});
|
||||
assertEquals("{\"hello\":\"world\"}", this.response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersString() throws Exception {
|
||||
this.request.addHeader("Accept", "text/plain");
|
||||
this.adapter.handle(this.request, this.response, new AbstractEndpoint<String>(
|
||||
"/foo") {
|
||||
@Override
|
||||
protected String doInvoke() {
|
||||
return "hello world";
|
||||
}
|
||||
});
|
||||
assertEquals("hello world", this.response.getContentAsString());
|
||||
}
|
||||
}
|
||||
@@ -16,12 +16,18 @@
|
||||
|
||||
package org.springframework.boot.actuate.endpoint.mvc;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
@@ -33,21 +39,38 @@ import static org.junit.Assert.assertThat;
|
||||
* Tests for {@link EndpointHandlerMapping}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class EndpointHandlerMappingTests {
|
||||
|
||||
private StaticApplicationContext context = new StaticApplicationContext();
|
||||
private EndpointHandlerMapping mapping = new EndpointHandlerMapping();
|
||||
private Method method;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton("mapping",
|
||||
this.mapping);
|
||||
this.mapping.setApplicationContext(this.context);
|
||||
this.method = ReflectionUtils.findMethod(TestEndpoint.class, "invoke");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withoutPrefix() throws Exception {
|
||||
TestEndpoint endpointA = new TestEndpoint("/a");
|
||||
TestEndpoint endpointB = new TestEndpoint("/b");
|
||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(Arrays.asList(
|
||||
endpointA, endpointB));
|
||||
mapping.afterPropertiesSet();
|
||||
assertThat(mapping.getHandler(new MockHttpServletRequest("GET", "/a"))
|
||||
.getHandler(), equalTo((Object) endpointA));
|
||||
assertThat(mapping.getHandler(new MockHttpServletRequest("GET", "/b"))
|
||||
.getHandler(), equalTo((Object) endpointB));
|
||||
assertThat(mapping.getHandler(new MockHttpServletRequest("GET", "/c")),
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton(
|
||||
endpointA.getPath(), endpointA);
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton(
|
||||
endpointB.getPath(), endpointB);
|
||||
this.mapping.afterPropertiesSet();
|
||||
assertThat(this.mapping.getHandler(new MockHttpServletRequest("GET", "/a"))
|
||||
.getHandler(),
|
||||
equalTo((Object) new HandlerMethod(endpointA, this.method)));
|
||||
assertThat(this.mapping.getHandler(new MockHttpServletRequest("GET", "/b"))
|
||||
.getHandler(),
|
||||
equalTo((Object) new HandlerMethod(endpointB, this.method)));
|
||||
assertThat(this.mapping.getHandler(new MockHttpServletRequest("GET", "/c")),
|
||||
nullValue());
|
||||
}
|
||||
|
||||
@@ -55,49 +78,63 @@ public class EndpointHandlerMappingTests {
|
||||
public void withPrefix() throws Exception {
|
||||
TestEndpoint endpointA = new TestEndpoint("/a");
|
||||
TestEndpoint endpointB = new TestEndpoint("/b");
|
||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(Arrays.asList(
|
||||
endpointA, endpointB));
|
||||
mapping.setPrefix("/a");
|
||||
mapping.afterPropertiesSet();
|
||||
assertThat(mapping.getHandler(new MockHttpServletRequest("GET", "/a/a"))
|
||||
.getHandler(), equalTo((Object) endpointA));
|
||||
assertThat(mapping.getHandler(new MockHttpServletRequest("GET", "/a/b"))
|
||||
.getHandler(), equalTo((Object) endpointB));
|
||||
assertThat(mapping.getHandler(new MockHttpServletRequest("GET", "/a")),
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton(
|
||||
endpointA.getPath(), endpointA);
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton(
|
||||
endpointB.getPath(), endpointB);
|
||||
this.mapping.setPrefix("/a");
|
||||
this.mapping.afterPropertiesSet();
|
||||
assertThat(this.mapping.getHandler(new MockHttpServletRequest("GET", "/a/a"))
|
||||
.getHandler(),
|
||||
equalTo((Object) new HandlerMethod(endpointA, this.method)));
|
||||
assertThat(this.mapping.getHandler(new MockHttpServletRequest("GET", "/a/b"))
|
||||
.getHandler(),
|
||||
equalTo((Object) new HandlerMethod(endpointB, this.method)));
|
||||
assertThat(this.mapping.getHandler(new MockHttpServletRequest("GET", "/a")),
|
||||
nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected = HttpRequestMethodNotSupportedException.class)
|
||||
public void onlyGetHttpMethodForNonActionEndpoints() throws Exception {
|
||||
TestEndpoint endpoint = new TestEndpoint("/a");
|
||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
||||
Arrays.asList(endpoint));
|
||||
mapping.afterPropertiesSet();
|
||||
assertNotNull(mapping.getHandler(new MockHttpServletRequest("GET", "/a")));
|
||||
assertNull(mapping.getHandler(new MockHttpServletRequest("POST", "/a")));
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton(
|
||||
endpoint.getPath(), endpoint);
|
||||
this.mapping.afterPropertiesSet();
|
||||
assertNotNull(this.mapping.getHandler(new MockHttpServletRequest("GET", "/a")));
|
||||
assertNull(this.mapping.getHandler(new MockHttpServletRequest("POST", "/a")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postHttpMethodForActionEndpoints() throws Exception {
|
||||
TestEndpoint endpoint = new TestActionEndpoint("/a");
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton(
|
||||
endpoint.getPath(), endpoint);
|
||||
this.mapping.afterPropertiesSet();
|
||||
assertNotNull(this.mapping.getHandler(new MockHttpServletRequest("POST", "/a")));
|
||||
}
|
||||
|
||||
@Test(expected = HttpRequestMethodNotSupportedException.class)
|
||||
public void onlyPostHttpMethodForActionEndpoints() throws Exception {
|
||||
TestEndpoint endpoint = new TestActionEndpoint("/a");
|
||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
||||
Arrays.asList(endpoint));
|
||||
mapping.afterPropertiesSet();
|
||||
assertNull(mapping.getHandler(new MockHttpServletRequest("GET", "/a")));
|
||||
assertNotNull(mapping.getHandler(new MockHttpServletRequest("POST", "/a")));
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton(
|
||||
endpoint.getPath(), endpoint);
|
||||
this.mapping.afterPropertiesSet();
|
||||
assertNotNull(this.mapping.getHandler(new MockHttpServletRequest("POST", "/a")));
|
||||
assertNull(this.mapping.getHandler(new MockHttpServletRequest("GET", "/a")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disabled() throws Exception {
|
||||
TestEndpoint endpointA = new TestEndpoint("/a");
|
||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
||||
Arrays.asList(endpointA));
|
||||
mapping.setDisabled(true);
|
||||
mapping.afterPropertiesSet();
|
||||
assertThat(mapping.getHandler(new MockHttpServletRequest("GET", "/a")),
|
||||
TestEndpoint endpoint = new TestEndpoint("/a");
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton(
|
||||
endpoint.getPath(), endpoint);
|
||||
this.mapping.setDisabled(true);
|
||||
this.mapping.afterPropertiesSet();
|
||||
assertThat(this.mapping.getHandler(new MockHttpServletRequest("GET", "/a")),
|
||||
nullValue());
|
||||
}
|
||||
|
||||
@FrameworkEndpoint
|
||||
private static class TestEndpoint extends AbstractEndpoint<Object> {
|
||||
|
||||
public TestEndpoint(String path) {
|
||||
@@ -105,12 +142,14 @@ public class EndpointHandlerMappingTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object doInvoke() {
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
public Object invoke() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@FrameworkEndpoint
|
||||
private static class TestActionEndpoint extends TestEndpoint {
|
||||
|
||||
public TestActionEndpoint(String path) {
|
||||
@@ -118,8 +157,9 @@ public class EndpointHandlerMappingTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpMethod[] methods() {
|
||||
return POST_HTTP_METHOD;
|
||||
@RequestMapping(method = RequestMethod.POST)
|
||||
public Object invoke() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,10 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.actuate.autoconfigure.ManagementSecurityAutoConfiguration;
|
||||
import org.springframework.boot.actuate.web.BasicErrorControllerIntegrationTests.TestConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -81,7 +83,8 @@ public class BasicErrorControllerIntegrationTests {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class,
|
||||
ManagementSecurityAutoConfiguration.class })
|
||||
public static class TestConfiguration {
|
||||
|
||||
// For manual testing
|
||||
|
||||
@@ -19,7 +19,9 @@ package org.springframework.boot.actuate.web;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.actuate.autoconfigure.ManagementSecurityAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -77,13 +79,15 @@ public class BasicErrorControllerSpecialIntegrationTests {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class,
|
||||
ManagementSecurityAutoConfiguration.class })
|
||||
protected static class ParentConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class,
|
||||
ManagementSecurityAutoConfiguration.class })
|
||||
@EnableWebMvc
|
||||
protected static class WebMvcIncludedConfiguration {
|
||||
// For manual testing
|
||||
@@ -94,7 +98,19 @@ public class BasicErrorControllerSpecialIntegrationTests {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class,
|
||||
ManagementSecurityAutoConfiguration.class })
|
||||
protected static class VanillaConfiguration {
|
||||
// For manual testing
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(VanillaConfiguration.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class,
|
||||
ManagementSecurityAutoConfiguration.class })
|
||||
protected static class ChildConfiguration {
|
||||
|
||||
// For manual testing
|
||||
|
||||
Reference in New Issue
Block a user