Merge branch '1.5.x'
This commit is contained in:
commit
65fe405f19
|
|
@ -37,6 +37,7 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.ActuatorMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoints;
|
||||
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
|
||||
|
|
@ -76,9 +77,9 @@ public class EndpointDocumentation {
|
|||
|
||||
static final File LOG_FILE = new File("target/logs/spring.log");
|
||||
|
||||
private static final Set<String> SKIPPED = Collections.<String>unmodifiableSet(
|
||||
new HashSet<String>(Arrays.asList("/docs", "/logfile", "/heapdump",
|
||||
"/auditevents")));
|
||||
private static final Set<String> SKIPPED = Collections
|
||||
.<String>unmodifiableSet(new HashSet<String>(
|
||||
Arrays.asList("/docs", "/logfile", "/heapdump", "/auditevents")));
|
||||
|
||||
@Autowired
|
||||
private MvcEndpoints mvcEndpoints;
|
||||
|
|
@ -123,34 +124,36 @@ public class EndpointDocumentation {
|
|||
public void setLogger() throws Exception {
|
||||
this.mockMvc
|
||||
.perform(post("/loggers/org.springframework.boot")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.contentType(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON)
|
||||
.content("{\"configuredLevel\": \"DEBUG\"}"))
|
||||
.andExpect(status().isOk()).andDo(document("set-logger"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void auditEvents() throws Exception {
|
||||
this.mockMvc.perform(get("/auditevents")
|
||||
.param("after", "2016-11-01T10:00:00+0000")
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
this.mockMvc
|
||||
.perform(get("/auditevents").param("after", "2016-11-01T10:00:00+0000")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON))
|
||||
.andExpect(status().isOk()).andDo(document("auditevents"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void auditEventsByPrincipal() throws Exception {
|
||||
this.mockMvc.perform(get("/auditevents").param("principal", "admin")
|
||||
this.mockMvc
|
||||
.perform(get("/auditevents").param("principal", "admin")
|
||||
.param("after", "2016-11-01T10:00:00+0000")
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(document("auditevents/filter-by-principal"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void auditEventsByPrincipalAndType() throws Exception {
|
||||
this.mockMvc.perform(get("/auditevents").param("principal", "admin")
|
||||
this.mockMvc
|
||||
.perform(get("/auditevents").param("principal", "admin")
|
||||
.param("after", "2016-11-01T10:00:00+0000")
|
||||
.param("type", "AUTHENTICATION_SUCCESS")
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(document("auditevents/filter-by-principal-and-type"));
|
||||
}
|
||||
|
|
@ -167,7 +170,9 @@ public class EndpointDocumentation {
|
|||
if (!SKIPPED.contains(endpointPath)) {
|
||||
String output = endpointPath.substring(1);
|
||||
output = output.length() > 0 ? output : "./";
|
||||
this.mockMvc.perform(get(endpointPath).accept(MediaType.APPLICATION_JSON))
|
||||
this.mockMvc
|
||||
.perform(get(endpointPath)
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON))
|
||||
.andExpect(status().isOk()).andDo(document(output))
|
||||
.andDo(new ResultHandler() {
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.ActuatorMediaTypes;
|
||||
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
|
@ -50,7 +50,9 @@ public class HealthEndpointDocumentation {
|
|||
|
||||
@Test
|
||||
public void health() throws Exception {
|
||||
this.mockMvc.perform(get("/health").accept(MediaType.APPLICATION_JSON))
|
||||
this.mockMvc
|
||||
.perform(get("/health")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON))
|
||||
.andExpect(status().isOk()).andDo(document("health/insensitive"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.ActuatorMediaTypes;
|
||||
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
|
@ -51,13 +51,17 @@ public class HypermediaEndpointDocumentation {
|
|||
|
||||
@Test
|
||||
public void beans() throws Exception {
|
||||
this.mockMvc.perform(get("/beans").accept(MediaType.APPLICATION_JSON))
|
||||
this.mockMvc
|
||||
.perform(get("/beans")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON))
|
||||
.andExpect(status().isOk()).andDo(document("beans/hypermedia"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void metrics() throws Exception {
|
||||
this.mockMvc.perform(get("/metrics").accept(MediaType.APPLICATION_JSON))
|
||||
this.mockMvc
|
||||
.perform(get("/metrics")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links.self.href")
|
||||
.value("http://localhost:8080/metrics"))
|
||||
|
|
@ -66,7 +70,9 @@ public class HypermediaEndpointDocumentation {
|
|||
|
||||
@Test
|
||||
public void home() throws Exception {
|
||||
this.mockMvc.perform(get("/actuator").accept(MediaType.APPLICATION_JSON))
|
||||
this.mockMvc
|
||||
.perform(get("/actuator")
|
||||
.accept(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON))
|
||||
.andExpect(status().isOk()).andDo(document("admin"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.actuate.autoconfigure;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -34,6 +35,7 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcHypermediaManagementContextConfiguration.EndpointHypermediaEnabledCondition;
|
||||
import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.ActuatorMediaTypes;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.DocsMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.HalBrowserMvcEndpoint;
|
||||
import org.springframework.boot.actuate.endpoint.mvc.HalJsonMvcEndpoint;
|
||||
|
|
@ -64,7 +66,9 @@ import org.springframework.hateoas.ResourceSupport;
|
|||
import org.springframework.hateoas.UriTemplate;
|
||||
import org.springframework.hateoas.hal.CurieProvider;
|
||||
import org.springframework.hateoas.hal.DefaultCurieProvider;
|
||||
import org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.AbstractHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
|
|
@ -221,13 +225,33 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration {
|
|||
*/
|
||||
@ConditionalOnProperty(prefix = "endpoints.hypermedia", name = "enabled", matchIfMissing = false)
|
||||
@ControllerAdvice(assignableTypes = MvcEndpoint.class)
|
||||
public static class MvcEndpointAdvice implements ResponseBodyAdvice<Object> {
|
||||
static class MvcEndpointAdvice implements ResponseBodyAdvice<Object> {
|
||||
|
||||
@Autowired
|
||||
private List<RequestMappingHandlerAdapter> handlerAdapters;
|
||||
private final List<RequestMappingHandlerAdapter> handlerAdapters;
|
||||
|
||||
private final Map<MediaType, HttpMessageConverter<?>> converterCache = new ConcurrentHashMap<MediaType, HttpMessageConverter<?>>();
|
||||
|
||||
MvcEndpointAdvice(List<RequestMappingHandlerAdapter> handlerAdapters) {
|
||||
this.handlerAdapters = handlerAdapters;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void configureHttpMessageConverters() {
|
||||
for (RequestMappingHandlerAdapter handlerAdapter : this.handlerAdapters) {
|
||||
for (HttpMessageConverter<?> messageConverter : handlerAdapter
|
||||
.getMessageConverters()) {
|
||||
if (messageConverter instanceof TypeConstrainedMappingJackson2HttpMessageConverter) {
|
||||
List<MediaType> supportedMediaTypes = new ArrayList<MediaType>(
|
||||
messageConverter.getSupportedMediaTypes());
|
||||
supportedMediaTypes
|
||||
.add(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON);
|
||||
((AbstractHttpMessageConverter<?>) messageConverter)
|
||||
.setSupportedMediaTypes(supportedMediaTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(MethodParameter returnType,
|
||||
Class<? extends HttpMessageConverter<?>> converterType) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2012-2017 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.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
/**
|
||||
* Specialized {@link RequestMapping} for {@link RequestMethod#GET GET} requests that
|
||||
* produce {@code application/json} or
|
||||
* {@code application/vnd.spring-boot.actuator.v1+json} responses.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@RequestMapping(method = RequestMethod.GET, produces = {
|
||||
ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE,
|
||||
MediaType.APPLICATION_JSON_VALUE })
|
||||
@interface ActuatorGetMapping {
|
||||
|
||||
/**
|
||||
* Alias for {@link RequestMapping#value}.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
@AliasFor(annotation = RequestMapping.class)
|
||||
String[] value() default {};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2012-2017 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 org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* {@link MediaType MediaTypes} that can be consumed and produced by Actuator endpoints.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public final class ActuatorMediaTypes {
|
||||
|
||||
/**
|
||||
* {@link String} equivalent of {@link #APPLICATION_ACTUATOR_V1_JSON}.
|
||||
*/
|
||||
public static final String APPLICATION_ACTUATOR_V1_JSON_VALUE = "application/vnd.spring-boot.actuator.v1+json";
|
||||
|
||||
/**
|
||||
* The {@code application/vnd.spring-boot.actuator.v1+json} media type.
|
||||
*/
|
||||
public static final MediaType APPLICATION_ACTUATOR_V1_JSON = MediaType
|
||||
.valueOf(APPLICATION_ACTUATOR_V1_JSON_VALUE);
|
||||
|
||||
private ActuatorMediaTypes() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2012-2017 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.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
/**
|
||||
* Specialized {@link RequestMapping} for {@link RequestMethod#POST POST} requests that
|
||||
* consume {@code application/json} or
|
||||
* {@code application/vnd.spring-boot.actuator.v1+json} requests and produce
|
||||
* {@code application/json} or {@code application/vnd.spring-boot.actuator.v1+json}
|
||||
* responses.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@RequestMapping(method = RequestMethod.POST, consumes = {
|
||||
ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE,
|
||||
MediaType.APPLICATION_JSON_VALUE }, produces = {
|
||||
ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE,
|
||||
MediaType.APPLICATION_JSON_VALUE })
|
||||
@interface ActuatorPostMapping {
|
||||
|
||||
/**
|
||||
* Alias for {@link RequestMapping#value}.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
@AliasFor(annotation = RequestMapping.class)
|
||||
String[] value() default {};
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -24,10 +24,8 @@ import org.springframework.boot.actuate.audit.AuditEvent;
|
|||
import org.springframework.boot.actuate.audit.AuditEventRepository;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
|
|
@ -49,7 +47,7 @@ public class AuditEventsMvcEndpoint extends AbstractNamedMvcEndpoint {
|
|||
this.auditEventRepository = auditEventRepository;
|
||||
}
|
||||
|
||||
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ActuatorGetMapping
|
||||
@ResponseBody
|
||||
public ResponseEntity<?> findByPrincipalAndAfterAndType(
|
||||
@RequestParam(required = false) String principal,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,8 +17,6 @@
|
|||
package org.springframework.boot.actuate.endpoint.mvc;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
|
|
@ -38,7 +36,7 @@ public class EndpointMvcAdapter extends AbstractEndpointMvcAdapter<Endpoint<?>>
|
|||
}
|
||||
|
||||
@Override
|
||||
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ActuatorGetMapping
|
||||
@ResponseBody
|
||||
public Object invoke() {
|
||||
return super.invoke();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -25,8 +25,6 @@ import org.springframework.core.env.Environment;
|
|||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.PropertySources;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
|
@ -48,7 +46,7 @@ public class EnvironmentMvcEndpoint extends EndpointMvcAdapter
|
|||
super(delegate);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/{name:.*}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ActuatorGetMapping("/{name:.*}")
|
||||
@ResponseBody
|
||||
@HypermediaDisabled
|
||||
public Object value(@PathVariable String name) {
|
||||
|
|
|
|||
|
|
@ -18,9 +18,7 @@ package org.springframework.boot.actuate.endpoint.mvc;
|
|||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
|
|
@ -49,7 +47,7 @@ public class HalJsonMvcEndpoint extends AbstractNamedMvcEndpoint {
|
|||
return "/actuator";
|
||||
}
|
||||
|
||||
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ActuatorGetMapping
|
||||
@ResponseBody
|
||||
public ResourceSupport links() {
|
||||
return new ResourceSupport();
|
||||
|
|
|
|||
|
|
@ -30,11 +30,9 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
|
|
@ -123,7 +121,7 @@ public class HealthMvcEndpoint extends AbstractEndpointMvcAdapter<HealthEndpoint
|
|||
this.statusMapping.put(statusCode, httpStatus);
|
||||
}
|
||||
|
||||
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ActuatorGetMapping
|
||||
@ResponseBody
|
||||
public Object invoke(HttpServletRequest request) {
|
||||
if (!getDelegate().isEnabled()) {
|
||||
|
|
|
|||
|
|
@ -23,11 +23,8 @@ import org.springframework.boot.actuate.endpoint.LoggersEndpoint.LoggerLevels;
|
|||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.logging.LogLevel;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
|
|
@ -48,7 +45,7 @@ public class LoggersMvcEndpoint extends EndpointMvcAdapter {
|
|||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@GetMapping(value = "/{name:.*}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ActuatorGetMapping("/{name:.*}")
|
||||
@ResponseBody
|
||||
@HypermediaDisabled
|
||||
public Object get(@PathVariable String name) {
|
||||
|
|
@ -61,7 +58,7 @@ public class LoggersMvcEndpoint extends EndpointMvcAdapter {
|
|||
return (levels == null ? ResponseEntity.notFound().build() : levels);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/{name:.*}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ActuatorPostMapping("/{name:.*}")
|
||||
@ResponseBody
|
||||
@HypermediaDisabled
|
||||
public Object set(@PathVariable String name,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
* Copyright 2012-2017 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.
|
||||
|
|
@ -21,8 +21,6 @@ import java.util.Map;
|
|||
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
|
@ -44,7 +42,7 @@ public class MetricsMvcEndpoint extends EndpointMvcAdapter {
|
|||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@GetMapping(value = "/{name:.*}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ActuatorGetMapping("/{name:.*}")
|
||||
@ResponseBody
|
||||
@HypermediaDisabled
|
||||
public Object value(@PathVariable String name) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
* Copyright 2012-2017 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.
|
||||
|
|
@ -22,6 +22,7 @@ import java.util.Map;
|
|||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
|
@ -38,7 +39,8 @@ public class ShutdownMvcEndpoint extends EndpointMvcAdapter {
|
|||
super(delegate);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PostMapping(produces = { ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE,
|
||||
MediaType.APPLICATION_JSON_VALUE })
|
||||
@ResponseBody
|
||||
@Override
|
||||
public Object invoke() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
* Copyright 2012-2017 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.
|
||||
|
|
@ -37,6 +37,8 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
|
@ -47,6 +49,7 @@ import static org.hamcrest.CoreMatchers.containsString;
|
|||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
|
|
@ -70,6 +73,21 @@ public class AuditEventsMvcEndpointTests {
|
|||
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentTypeDefaultsToActuatorV1Json() throws Exception {
|
||||
this.mvc.perform(get("/auditevents")).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
"application/vnd.spring-boot.actuator.v1+json;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentTypeCanBeApplicationJson() throws Exception {
|
||||
this.mvc.perform(get("/auditevents").header(HttpHeaders.ACCEPT,
|
||||
MediaType.APPLICATION_JSON_VALUE)).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
MediaType.APPLICATION_JSON_UTF8_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeWhenDisabledShouldReturnNotFoundStatus() throws Exception {
|
||||
this.context.getBean(AuditEventsMvcEndpoint.class).setEnabled(false);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ import org.springframework.context.annotation.Configuration;
|
|||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
|
@ -49,6 +51,7 @@ import org.springframework.web.context.WebApplicationContext;
|
|||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
|
|
@ -76,6 +79,36 @@ public class EnvironmentMvcEndpointTests {
|
|||
"foo:bar", "fool:baz");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void homeContentTypeDefaultsToActuatorV1Json() throws Exception {
|
||||
this.mvc.perform(get("/env")).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
"application/vnd.spring-boot.actuator.v1+json;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void homeContentTypeCanBeApplicationJson() throws Exception {
|
||||
this.mvc.perform(
|
||||
get("/env").header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE))
|
||||
.andExpect(status().isOk()).andExpect(header().string("Content-Type",
|
||||
MediaType.APPLICATION_JSON_UTF8_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subContentTypeDefaultsToActuatorV1Json() throws Exception {
|
||||
this.mvc.perform(get("/env/foo")).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
"application/vnd.spring-boot.actuator.v1+json;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subContentTypeCanBeApplicationJson() throws Exception {
|
||||
this.mvc.perform(get("/env/foo").header(HttpHeaders.ACCEPT,
|
||||
MediaType.APPLICATION_JSON_VALUE)).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
MediaType.APPLICATION_JSON_UTF8_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void home() throws Exception {
|
||||
this.mvc.perform(get("/env")).andExpect(status().isOk())
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
* Copyright 2012-2017 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.
|
||||
|
|
@ -61,17 +61,13 @@ public class HealthMvcEndpointTests {
|
|||
|
||||
private MockEnvironment environment;
|
||||
|
||||
private HttpServletRequest user = createAuthenticationToken(
|
||||
"ROLE_USER");
|
||||
private HttpServletRequest user = createAuthenticationToken("ROLE_USER");
|
||||
|
||||
private HttpServletRequest actuator = createAuthenticationToken(
|
||||
"ROLE_ACTUATOR");
|
||||
private HttpServletRequest actuator = createAuthenticationToken("ROLE_ACTUATOR");
|
||||
|
||||
private HttpServletRequest hero = createAuthenticationToken(
|
||||
"ROLE_HERO");
|
||||
private HttpServletRequest hero = createAuthenticationToken("ROLE_HERO");
|
||||
|
||||
private HttpServletRequest createAuthenticationToken(
|
||||
String role) {
|
||||
private HttpServletRequest createAuthenticationToken(String role) {
|
||||
MockServletContext servletContext = new MockServletContext();
|
||||
servletContext.declareRoles(role);
|
||||
return new MockHttpServletRequest(servletContext);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
* Copyright 2012-2017 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.
|
||||
|
|
@ -38,6 +38,8 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
|
@ -47,6 +49,7 @@ import org.springframework.web.context.WebApplicationContext;
|
|||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
|
|
@ -80,6 +83,21 @@ public class InfoMvcEndpointTests {
|
|||
"\"beanName2\":{\"key21\":\"value21\",\"key22\":\"value22\"}")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentTypeDefaultsToActuatorV1Json() throws Exception {
|
||||
this.mvc.perform(get("/info")).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
"application/vnd.spring-boot.actuator.v1+json;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentTypeCanBeApplicationJson() throws Exception {
|
||||
this.mvc.perform(
|
||||
get("/info").header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE))
|
||||
.andExpect(status().isOk()).andExpect(header().string("Content-Type",
|
||||
MediaType.APPLICATION_JSON_UTF8_VALUE));
|
||||
}
|
||||
|
||||
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
|
||||
HttpMessageConvertersAutoConfiguration.class,
|
||||
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
|
@ -55,6 +56,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
|
|||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
|
|
@ -129,12 +131,35 @@ public class LoggersMvcEndpointTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void setLoggerShouldSetLogLevel() throws Exception {
|
||||
public void contentTypeForGetDefaultsToActuatorV1Json() throws Exception {
|
||||
this.mvc.perform(get("/loggers")).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
"application/vnd.spring-boot.actuator.v1+json;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentTypeForGetCanBeApplicationJson() throws Exception {
|
||||
this.mvc.perform(get("/loggers").header(HttpHeaders.ACCEPT,
|
||||
MediaType.APPLICATION_JSON_VALUE)).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
MediaType.APPLICATION_JSON_UTF8_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLoggerUsingApplicationJsonShouldSetLogLevel() throws Exception {
|
||||
this.mvc.perform(post("/loggers/ROOT").contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"configuredLevel\":\"debug\"}")).andExpect(status().isOk());
|
||||
verify(this.loggingSystem).setLogLevel("ROOT", LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLoggerUsingActuatorV1JsonShouldSetLogLevel() throws Exception {
|
||||
this.mvc.perform(post("/loggers/ROOT")
|
||||
.contentType(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON)
|
||||
.content("{\"configuredLevel\":\"debug\"}")).andExpect(status().isOk());
|
||||
verify(this.loggingSystem).setLogLevel("ROOT", LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setLoggerWhenDisabledShouldReturnNotFound() throws Exception {
|
||||
this.context.getBean(LoggersEndpoint.class).setEnabled(false);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
* Copyright 2012-2017 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.
|
||||
|
|
@ -38,6 +38,8 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
|
@ -49,6 +51,7 @@ import static org.hamcrest.Matchers.containsString;
|
|||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
|
|
@ -80,6 +83,36 @@ public class MetricsMvcEndpointTests {
|
|||
.andExpect(content().string(containsString("\"foo\":1")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void homeContentTypeDefaultsToActuatorV1Json() throws Exception {
|
||||
this.mvc.perform(get("/metrics")).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
"application/vnd.spring-boot.actuator.v1+json;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void homeContentTypeCanBeApplicationJson() throws Exception {
|
||||
this.mvc.perform(get("/metrics").header(HttpHeaders.ACCEPT,
|
||||
MediaType.APPLICATION_JSON_VALUE)).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
MediaType.APPLICATION_JSON_UTF8_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void specificMetricContentTypeDefaultsToActuatorV1Json() throws Exception {
|
||||
this.mvc.perform(get("/metrics/foo")).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
"application/vnd.spring-boot.actuator.v1+json;charset=UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void specificMetricContentTypeCanBeApplicationJson() throws Exception {
|
||||
this.mvc.perform(get("/metrics/foo").header(HttpHeaders.ACCEPT,
|
||||
MediaType.APPLICATION_JSON_VALUE)).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
MediaType.APPLICATION_JSON_UTF8_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void homeWhenDisabled() throws Exception {
|
||||
this.context.getBean(MetricsEndpoint.class).setEnabled(false);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
* Copyright 2012-2017 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.
|
||||
|
|
@ -16,34 +16,127 @@
|
|||
|
||||
package org.springframework.boot.actuate.endpoint.mvc;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.willAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* Tests for {@link ShutdownMvcEndpoint}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@SpringBootTest(properties = { "management.security.enabled=false",
|
||||
"endpoints.shutdown.enabled=true" })
|
||||
@RunWith(SpringRunner.class)
|
||||
public class ShutdownMvcEndpointTests {
|
||||
|
||||
private ShutdownEndpoint endpoint = mock(ShutdownEndpoint.class);
|
||||
@Autowired
|
||||
private WebApplicationContext context;
|
||||
|
||||
private ShutdownMvcEndpoint mvc = new ShutdownMvcEndpoint(this.endpoint);
|
||||
private MockMvc mvc;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disabled() {
|
||||
@SuppressWarnings("unchecked")
|
||||
ResponseEntity<Map<String, String>> response = (ResponseEntity<Map<String, String>>) this.mvc
|
||||
.invoke();
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
|
||||
public void contentTypeDefaultsToActuatorV1Json() throws Exception {
|
||||
this.mvc.perform(post("/shutdown")).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
"application/vnd.spring-boot.actuator.v1+json;charset=UTF-8"));
|
||||
assertThat(this.context.getBean(CountDownLatch.class).await(30, TimeUnit.SECONDS))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentTypeCanBeApplicationJson() throws Exception {
|
||||
this.mvc.perform(post("/shutdown").header(HttpHeaders.ACCEPT,
|
||||
MediaType.APPLICATION_JSON_VALUE)).andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Type",
|
||||
MediaType.APPLICATION_JSON_UTF8_VALUE));
|
||||
assertThat(this.context.getBean(CountDownLatch.class).await(30, TimeUnit.SECONDS))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import({ JacksonAutoConfiguration.class,
|
||||
HttpMessageConvertersAutoConfiguration.class,
|
||||
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
|
||||
ManagementServerPropertiesAutoConfiguration.class })
|
||||
public static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public TestShutdownEndpoint endpoint() {
|
||||
return new TestShutdownEndpoint(contextCloseLatch());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CountDownLatch contextCloseLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TestShutdownEndpoint extends ShutdownEndpoint {
|
||||
|
||||
private final CountDownLatch contextCloseLatch;
|
||||
|
||||
TestShutdownEndpoint(CountDownLatch contextCloseLatch) {
|
||||
this.contextCloseLatch = contextCloseLatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context)
|
||||
throws BeansException {
|
||||
ConfigurableApplicationContext mockContext = mock(
|
||||
ConfigurableApplicationContext.class);
|
||||
willAnswer(new Answer<Void>() {
|
||||
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
TestShutdownEndpoint.this.contextCloseLatch.countDown();
|
||||
return null;
|
||||
}
|
||||
|
||||
}).given(mockContext).close();
|
||||
super.setApplicationContext(mockContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
|
||||
package org.springframework.boot.autoconfigure.hateoas;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
|
@ -29,9 +30,9 @@ import org.springframework.beans.factory.ListableBeanFactory;
|
|||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.AbstractHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
|
||||
|
|
@ -72,10 +73,14 @@ public class HypermediaHttpMessageConverterConfiguration {
|
|||
for (HttpMessageConverter<?> converter : handlerAdapter
|
||||
.getMessageConverters()) {
|
||||
if (converter instanceof TypeConstrainedMappingJackson2HttpMessageConverter) {
|
||||
((TypeConstrainedMappingJackson2HttpMessageConverter) converter)
|
||||
.setSupportedMediaTypes(
|
||||
Arrays.asList(MediaTypes.HAL_JSON,
|
||||
MediaType.APPLICATION_JSON));
|
||||
List<MediaType> supportedMediaTypes = new ArrayList<MediaType>(
|
||||
converter.getSupportedMediaTypes());
|
||||
if (!supportedMediaTypes
|
||||
.contains(MediaType.APPLICATION_JSON)) {
|
||||
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
|
||||
}
|
||||
((AbstractHttpMessageConverter<?>) converter)
|
||||
.setSupportedMediaTypes(supportedMediaTypes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue