Merge branch '1.5.x'
This commit is contained in:
commit
277d01ab53
|
|
@ -83,12 +83,7 @@ public class EndpointWebMvcManagementContextConfiguration {
|
||||||
CorsConfiguration corsConfiguration = getCorsConfiguration(this.corsProperties);
|
CorsConfiguration corsConfiguration = getCorsConfiguration(this.corsProperties);
|
||||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(endpoints,
|
EndpointHandlerMapping mapping = new EndpointHandlerMapping(endpoints,
|
||||||
corsConfiguration);
|
corsConfiguration);
|
||||||
boolean disabled = this.managementServerProperties.getPort() != null
|
|
||||||
&& this.managementServerProperties.getPort() == -1;
|
|
||||||
mapping.setDisabled(disabled);
|
|
||||||
if (!disabled) {
|
|
||||||
mapping.setPrefix(this.managementServerProperties.getContextPath());
|
mapping.setPrefix(this.managementServerProperties.getContextPath());
|
||||||
}
|
|
||||||
if (this.mappingCustomizers != null) {
|
if (this.mappingCustomizers != null) {
|
||||||
for (EndpointHandlerMappingCustomizer customizer : this.mappingCustomizers) {
|
for (EndpointHandlerMappingCustomizer customizer : this.mappingCustomizers) {
|
||||||
customizer.customize(mapping);
|
customizer.customize(mapping);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import org.springframework.util.Assert;
|
||||||
* @since 1.3.0
|
* @since 1.3.0
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractEndpointMvcAdapter<E extends Endpoint<?>>
|
public abstract class AbstractEndpointMvcAdapter<E extends Endpoint<?>>
|
||||||
implements MvcEndpoint {
|
implements NamedMvcEndpoint {
|
||||||
|
|
||||||
private final E delegate;
|
private final E delegate;
|
||||||
|
|
||||||
|
|
@ -60,6 +60,11 @@ public abstract class AbstractEndpointMvcAdapter<E extends Endpoint<?>>
|
||||||
return this.delegate;
|
return this.delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return this.delegate.getId();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return (this.path != null ? this.path : "/" + this.delegate.getId());
|
return (this.path != null ? this.path : "/" + this.delegate.getId());
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.actuate.endpoint.mvc;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class for {@link NamedMvcEndpoint} implementations without a backing
|
||||||
|
* {@link Endpoint}.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public class AbstractNamedMvcEndpoint extends AbstractMvcEndpoint
|
||||||
|
implements NamedMvcEndpoint {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public AbstractNamedMvcEndpoint(String name, String path, boolean sensitive) {
|
||||||
|
super(path, sensitive);
|
||||||
|
Assert.hasLength(name, "Name must not be empty");
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractNamedMvcEndpoint(String name, String path, boolean sensitive,
|
||||||
|
boolean enabled) {
|
||||||
|
super(path, sensitive, enabled);
|
||||||
|
Assert.hasLength(name, "Name must not be empty");
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
|
||||||
* @since 1.3.0
|
* @since 1.3.0
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties("endpoints.docs")
|
@ConfigurationProperties("endpoints.docs")
|
||||||
public class DocsMvcEndpoint extends AbstractMvcEndpoint {
|
public class DocsMvcEndpoint extends AbstractNamedMvcEndpoint {
|
||||||
|
|
||||||
private static final String DOCS_LOCATION = "classpath:/META-INF/resources/spring-boot-actuator/docs/";
|
private static final String DOCS_LOCATION = "classpath:/META-INF/resources/spring-boot-actuator/docs/";
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@ public class DocsMvcEndpoint extends AbstractMvcEndpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DocsMvcEndpoint(ManagementServletContext managementServletContext) {
|
public DocsMvcEndpoint(ManagementServletContext managementServletContext) {
|
||||||
super("/docs", false);
|
super("docs", "/docs", false);
|
||||||
this.managementServletContext = managementServletContext;
|
this.managementServletContext = managementServletContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.mvc;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
@ -26,6 +27,7 @@ import java.util.Set;
|
||||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
|
@ -113,31 +115,42 @@ public class EndpointHandlerMapping extends RequestMappingHandlerMapping {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String[] patterns = getPatterns(handler, mapping);
|
String[] patterns = getPatterns(handler, mapping);
|
||||||
super.registerHandlerMethod(handler, method, withNewPatterns(mapping, patterns));
|
if (!ObjectUtils.isEmpty(patterns)) {
|
||||||
|
super.registerHandlerMethod(handler, method,
|
||||||
|
withNewPatterns(mapping, patterns));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] getPatterns(Object handler, RequestMappingInfo mapping) {
|
private String[] getPatterns(Object handler, RequestMappingInfo mapping) {
|
||||||
String path = getPath(handler);
|
|
||||||
String prefix = StringUtils.hasText(this.prefix) ? this.prefix + path : path;
|
|
||||||
Set<String> defaultPatterns = mapping.getPatternsCondition().getPatterns();
|
|
||||||
if (defaultPatterns.isEmpty()) {
|
|
||||||
return new String[] { prefix, prefix + ".json" };
|
|
||||||
}
|
|
||||||
List<String> patterns = new ArrayList<String>(defaultPatterns);
|
|
||||||
for (int i = 0; i < patterns.size(); i++) {
|
|
||||||
patterns.set(i, prefix + patterns.get(i));
|
|
||||||
}
|
|
||||||
return patterns.toArray(new String[patterns.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getPath(Object handler) {
|
|
||||||
if (handler instanceof String) {
|
if (handler instanceof String) {
|
||||||
handler = getApplicationContext().getBean((String) handler);
|
handler = getApplicationContext().getBean((String) handler);
|
||||||
}
|
}
|
||||||
if (handler instanceof MvcEndpoint) {
|
Assert.state(handler instanceof MvcEndpoint, "Only MvcEndpoints are supported");
|
||||||
return ((MvcEndpoint) handler).getPath();
|
String path = getPath((MvcEndpoint) handler);
|
||||||
|
return (path == null ? null : getEndpointPatterns(path, mapping));
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
|
/**
|
||||||
|
* Return the path that should be used to map the given {@link MvcEndpoint}.
|
||||||
|
* @param endpoint the endpoint to map
|
||||||
|
* @return the path to use for the endpoint or {@code null} if no mapping is required
|
||||||
|
*/
|
||||||
|
protected String getPath(MvcEndpoint endpoint) {
|
||||||
|
return endpoint.getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] getEndpointPatterns(String path, RequestMappingInfo mapping) {
|
||||||
|
String patternPrefix = StringUtils.hasText(this.prefix) ? this.prefix + path
|
||||||
|
: path;
|
||||||
|
Set<String> defaultPatterns = mapping.getPatternsCondition().getPatterns();
|
||||||
|
if (defaultPatterns.isEmpty()) {
|
||||||
|
return new String[] { patternPrefix, patternPrefix + ".json" };
|
||||||
|
}
|
||||||
|
List<String> patterns = new ArrayList<String>(defaultPatterns);
|
||||||
|
for (int i = 0; i < patterns.size(); i++) {
|
||||||
|
patterns.set(i, patternPrefix + patterns.get(i));
|
||||||
|
}
|
||||||
|
return patterns.toArray(new String[patterns.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping,
|
private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping,
|
||||||
|
|
@ -196,9 +209,29 @@ public class EndpointHandlerMapping extends RequestMappingHandlerMapping {
|
||||||
/**
|
/**
|
||||||
* Return the endpoints.
|
* Return the endpoints.
|
||||||
* @return the endpoints
|
* @return the endpoints
|
||||||
|
* @see #getEndpoints(Class)
|
||||||
*/
|
*/
|
||||||
public Set<? extends MvcEndpoint> getEndpoints() {
|
public Set<? extends MvcEndpoint> getEndpoints() {
|
||||||
return new HashSet<MvcEndpoint>(this.endpoints);
|
return getEndpoints(MvcEndpoint.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the endpoints of the specified type.
|
||||||
|
* @param <E> the endpoint type
|
||||||
|
* @param type the endpoint type
|
||||||
|
* @return the endpoints
|
||||||
|
* @see #getEndpoints()
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <E extends MvcEndpoint> Set<E> getEndpoints(Class<E> type) {
|
||||||
|
Set<E> result = new HashSet<E>(this.endpoints.size());
|
||||||
|
for (MvcEndpoint candidate : this.endpoints) {
|
||||||
|
if (type.isInstance(candidate)) {
|
||||||
|
result.add((E) candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableSet(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,12 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
* @since 1.3.0
|
* @since 1.3.0
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties("endpoints.actuator")
|
@ConfigurationProperties("endpoints.actuator")
|
||||||
public class HalJsonMvcEndpoint extends AbstractMvcEndpoint {
|
public class HalJsonMvcEndpoint extends AbstractNamedMvcEndpoint {
|
||||||
|
|
||||||
private final ManagementServletContext managementServletContext;
|
private final ManagementServletContext managementServletContext;
|
||||||
|
|
||||||
public HalJsonMvcEndpoint(ManagementServletContext managementServletContext) {
|
public HalJsonMvcEndpoint(ManagementServletContext managementServletContext) {
|
||||||
super(getDefaultPath(managementServletContext), false);
|
super("actuator", getDefaultPath(managementServletContext), false);
|
||||||
this.managementServletContext = managementServletContext;
|
this.managementServletContext = managementServletContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties("endpoints.heapdump")
|
@ConfigurationProperties("endpoints.heapdump")
|
||||||
@HypermediaDisabled
|
@HypermediaDisabled
|
||||||
public class HeapdumpMvcEndpoint extends AbstractMvcEndpoint {
|
public class HeapdumpMvcEndpoint extends AbstractNamedMvcEndpoint {
|
||||||
|
|
||||||
private final long timeout;
|
private final long timeout;
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@ public class HeapdumpMvcEndpoint extends AbstractMvcEndpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HeapdumpMvcEndpoint(long timeout) {
|
protected HeapdumpMvcEndpoint(long timeout) {
|
||||||
super("/heapdump", true);
|
super("heapdump", "/heapdump", true);
|
||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,12 +44,12 @@ import org.springframework.web.util.UrlPathHelper;
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties(prefix = "endpoints.jolokia", ignoreUnknownFields = false)
|
@ConfigurationProperties(prefix = "endpoints.jolokia", ignoreUnknownFields = false)
|
||||||
@HypermediaDisabled
|
@HypermediaDisabled
|
||||||
public class JolokiaMvcEndpoint extends AbstractMvcEndpoint
|
public class JolokiaMvcEndpoint extends AbstractNamedMvcEndpoint
|
||||||
implements InitializingBean, ApplicationContextAware, ServletContextAware {
|
implements InitializingBean, ApplicationContextAware, ServletContextAware {
|
||||||
private final ServletWrappingController controller = new ServletWrappingController();
|
private final ServletWrappingController controller = new ServletWrappingController();
|
||||||
|
|
||||||
public JolokiaMvcEndpoint() {
|
public JolokiaMvcEndpoint() {
|
||||||
super("/jolokia", true);
|
super("jolokia", "/jolokia", true);
|
||||||
this.controller.setServletClass(AgentServlet.class);
|
this.controller.setServletClass(AgentServlet.class);
|
||||||
this.controller.setServletName("jolokia");
|
this.controller.setServletName("jolokia");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
|
||||||
* @since 1.3.0
|
* @since 1.3.0
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties(prefix = "endpoints.logfile")
|
@ConfigurationProperties(prefix = "endpoints.logfile")
|
||||||
public class LogFileMvcEndpoint extends AbstractMvcEndpoint {
|
public class LogFileMvcEndpoint extends AbstractNamedMvcEndpoint {
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(LogFileMvcEndpoint.class);
|
private static final Log logger = LogFactory.getLog(LogFileMvcEndpoint.class);
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ public class LogFileMvcEndpoint extends AbstractMvcEndpoint {
|
||||||
private File externalFile;
|
private File externalFile;
|
||||||
|
|
||||||
public LogFileMvcEndpoint() {
|
public LogFileMvcEndpoint() {
|
||||||
super("/logfile", true);
|
super("logfile", "/logfile", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getExternalFile() {
|
public File getExternalFile() {
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import org.springframework.http.ResponseEntity;
|
||||||
* {@link EndpointHandlerMapping}).
|
* {@link EndpointHandlerMapping}).
|
||||||
*
|
*
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
|
* @see NamedMvcEndpoint
|
||||||
*/
|
*/
|
||||||
public interface MvcEndpoint {
|
public interface MvcEndpoint {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.actuate.endpoint.mvc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link MvcEndpoint} that also includes a logical name. Unlike {@link #getPath()
|
||||||
|
* endpoints paths}, it should not be possible for a user to change the endpoint name.
|
||||||
|
* Names provide a consistent way to reference an endpoint, for example they may be used
|
||||||
|
* as the {@literal 'rel'} attribute in a HAL response.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
public interface NamedMvcEndpoint extends MvcEndpoint {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the logical name of the endpoint. Names should be non-null, non-empty,
|
||||||
|
* alpha-numeric values.
|
||||||
|
* @return the logical name of the endpoint
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.actuate.endpoint.mvc;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
@ -41,6 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
public class EndpointHandlerMappingTests {
|
public class EndpointHandlerMappingTests {
|
||||||
|
|
||||||
private final StaticApplicationContext context = new StaticApplicationContext();
|
private final StaticApplicationContext context = new StaticApplicationContext();
|
||||||
|
|
||||||
private Method method;
|
private Method method;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
@ -50,8 +52,8 @@ public class EndpointHandlerMappingTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void withoutPrefix() throws Exception {
|
public void withoutPrefix() throws Exception {
|
||||||
TestMvcEndpoint endpointA = new TestMvcEndpoint(new TestEndpoint("/a"));
|
TestMvcEndpoint endpointA = new TestMvcEndpoint(new TestEndpoint("a"));
|
||||||
TestMvcEndpoint endpointB = new TestMvcEndpoint(new TestEndpoint("/b"));
|
TestMvcEndpoint endpointB = new TestMvcEndpoint(new TestEndpoint("b"));
|
||||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
||||||
Arrays.asList(endpointA, endpointB));
|
Arrays.asList(endpointA, endpointB));
|
||||||
mapping.setApplicationContext(this.context);
|
mapping.setApplicationContext(this.context);
|
||||||
|
|
@ -65,8 +67,8 @@ public class EndpointHandlerMappingTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void withPrefix() throws Exception {
|
public void withPrefix() throws Exception {
|
||||||
TestMvcEndpoint endpointA = new TestMvcEndpoint(new TestEndpoint("/a"));
|
TestMvcEndpoint endpointA = new TestMvcEndpoint(new TestEndpoint("a"));
|
||||||
TestMvcEndpoint endpointB = new TestMvcEndpoint(new TestEndpoint("/b"));
|
TestMvcEndpoint endpointB = new TestMvcEndpoint(new TestEndpoint("b"));
|
||||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
||||||
Arrays.asList(endpointA, endpointB));
|
Arrays.asList(endpointA, endpointB));
|
||||||
mapping.setApplicationContext(this.context);
|
mapping.setApplicationContext(this.context);
|
||||||
|
|
@ -81,7 +83,7 @@ public class EndpointHandlerMappingTests {
|
||||||
|
|
||||||
@Test(expected = HttpRequestMethodNotSupportedException.class)
|
@Test(expected = HttpRequestMethodNotSupportedException.class)
|
||||||
public void onlyGetHttpMethodForNonActionEndpoints() throws Exception {
|
public void onlyGetHttpMethodForNonActionEndpoints() throws Exception {
|
||||||
TestActionEndpoint endpoint = new TestActionEndpoint(new TestEndpoint("/a"));
|
TestActionEndpoint endpoint = new TestActionEndpoint(new TestEndpoint("a"));
|
||||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
||||||
Arrays.asList(endpoint));
|
Arrays.asList(endpoint));
|
||||||
mapping.setApplicationContext(this.context);
|
mapping.setApplicationContext(this.context);
|
||||||
|
|
@ -92,7 +94,7 @@ public class EndpointHandlerMappingTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void postHttpMethodForActionEndpoints() throws Exception {
|
public void postHttpMethodForActionEndpoints() throws Exception {
|
||||||
TestActionEndpoint endpoint = new TestActionEndpoint(new TestEndpoint("/a"));
|
TestActionEndpoint endpoint = new TestActionEndpoint(new TestEndpoint("a"));
|
||||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
||||||
Arrays.asList(endpoint));
|
Arrays.asList(endpoint));
|
||||||
mapping.setApplicationContext(this.context);
|
mapping.setApplicationContext(this.context);
|
||||||
|
|
@ -102,7 +104,7 @@ public class EndpointHandlerMappingTests {
|
||||||
|
|
||||||
@Test(expected = HttpRequestMethodNotSupportedException.class)
|
@Test(expected = HttpRequestMethodNotSupportedException.class)
|
||||||
public void onlyPostHttpMethodForActionEndpoints() throws Exception {
|
public void onlyPostHttpMethodForActionEndpoints() throws Exception {
|
||||||
TestActionEndpoint endpoint = new TestActionEndpoint(new TestEndpoint("/a"));
|
TestActionEndpoint endpoint = new TestActionEndpoint(new TestEndpoint("a"));
|
||||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
||||||
Arrays.asList(endpoint));
|
Arrays.asList(endpoint));
|
||||||
mapping.setApplicationContext(this.context);
|
mapping.setApplicationContext(this.context);
|
||||||
|
|
@ -113,7 +115,7 @@ public class EndpointHandlerMappingTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void disabled() throws Exception {
|
public void disabled() throws Exception {
|
||||||
TestMvcEndpoint endpoint = new TestMvcEndpoint(new TestEndpoint("/a"));
|
TestMvcEndpoint endpoint = new TestMvcEndpoint(new TestEndpoint("a"));
|
||||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
||||||
Arrays.asList(endpoint));
|
Arrays.asList(endpoint));
|
||||||
mapping.setDisabled(true);
|
mapping.setDisabled(true);
|
||||||
|
|
@ -124,8 +126,8 @@ public class EndpointHandlerMappingTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void duplicatePath() throws Exception {
|
public void duplicatePath() throws Exception {
|
||||||
TestMvcEndpoint endpoint = new TestMvcEndpoint(new TestEndpoint("/a"));
|
TestMvcEndpoint endpoint = new TestMvcEndpoint(new TestEndpoint("a"));
|
||||||
TestActionEndpoint other = new TestActionEndpoint(new TestEndpoint("/a"));
|
TestActionEndpoint other = new TestActionEndpoint(new TestEndpoint("a"));
|
||||||
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
||||||
Arrays.asList(endpoint, other));
|
Arrays.asList(endpoint, other));
|
||||||
mapping.setDisabled(true);
|
mapping.setDisabled(true);
|
||||||
|
|
@ -135,14 +137,36 @@ public class EndpointHandlerMappingTests {
|
||||||
assertThat(mapping.getHandler(request("POST", "/a"))).isNull();
|
assertThat(mapping.getHandler(request("POST", "/a"))).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getEndpointsForSpecifiedType() throws Exception {
|
||||||
|
TestMvcEndpoint endpoint = new TestMvcEndpoint(new TestEndpoint("a"));
|
||||||
|
TestActionEndpoint other = new TestActionEndpoint(new TestEndpoint("b"));
|
||||||
|
EndpointHandlerMapping mapping = new EndpointHandlerMapping(
|
||||||
|
Arrays.asList(endpoint, other));
|
||||||
|
assertThat(mapping.getEndpoints(TestMvcEndpoint.class)).containsExactly(endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pathNotMappedWhenGetPathReturnsNull() throws Exception {
|
||||||
|
TestMvcEndpoint endpoint = new TestMvcEndpoint(new TestEndpoint("a"));
|
||||||
|
TestActionEndpoint other = new TestActionEndpoint(new TestEndpoint("b"));
|
||||||
|
EndpointHandlerMapping mapping = new TestEndpointHandlerMapping(
|
||||||
|
Arrays.asList(endpoint, other));
|
||||||
|
mapping.setApplicationContext(this.context);
|
||||||
|
mapping.afterPropertiesSet();
|
||||||
|
assertThat(mapping.getHandlerMethods()).hasSize(1);
|
||||||
|
assertThat(mapping.getHandler(request("GET", "/a"))).isNull();
|
||||||
|
assertThat(mapping.getHandler(request("POST", "/b"))).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
private MockHttpServletRequest request(String method, String requestURI) {
|
private MockHttpServletRequest request(String method, String requestURI) {
|
||||||
return new MockHttpServletRequest(method, requestURI);
|
return new MockHttpServletRequest(method, requestURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestEndpoint extends AbstractEndpoint<Object> {
|
private static class TestEndpoint extends AbstractEndpoint<Object> {
|
||||||
|
|
||||||
TestEndpoint(String path) {
|
TestEndpoint(String id) {
|
||||||
super(path);
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -174,4 +198,20 @@ public class EndpointHandlerMappingTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class TestEndpointHandlerMapping extends EndpointHandlerMapping {
|
||||||
|
|
||||||
|
TestEndpointHandlerMapping(Collection<? extends MvcEndpoint> endpoints) {
|
||||||
|
super(endpoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getPath(MvcEndpoint endpoint) {
|
||||||
|
if (endpoint instanceof TestActionEndpoint) {
|
||||||
|
return super.getPath(endpoint);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.condition;
|
||||||
|
|
||||||
|
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.boot.cloud.CloudPlatform;
|
||||||
|
import org.springframework.context.annotation.Conditional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Conditional} that matches when the specified cloud platform is active.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Conditional(OnCloudPlatformCondition.class)
|
||||||
|
public @interface ConditionalOnCloudPlatform {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link CloudPlatform cloud platform} that must be active.
|
||||||
|
* @return the expected cloud platform
|
||||||
|
*/
|
||||||
|
CloudPlatform value();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.condition;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.boot.cloud.CloudPlatform;
|
||||||
|
import org.springframework.context.annotation.Condition;
|
||||||
|
import org.springframework.context.annotation.ConditionContext;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Condition} that checks for a required {@link CloudPlatform}.
|
||||||
|
*
|
||||||
|
* @author Madhura Bhave
|
||||||
|
* @see ConditionalOnCloudPlatform
|
||||||
|
*/
|
||||||
|
class OnCloudPlatformCondition extends SpringBootCondition {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||||
|
AnnotatedTypeMetadata metadata) {
|
||||||
|
Map<String, Object> attributes = metadata
|
||||||
|
.getAnnotationAttributes(ConditionalOnCloudPlatform.class.getName());
|
||||||
|
CloudPlatform cloudPlatform = (CloudPlatform) attributes.get("value");
|
||||||
|
return getMatchOutcome(context.getEnvironment(), cloudPlatform);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConditionOutcome getMatchOutcome(Environment environment,
|
||||||
|
CloudPlatform cloudPlatform) {
|
||||||
|
String name = cloudPlatform.name();
|
||||||
|
ConditionMessage.Builder message = ConditionMessage
|
||||||
|
.forCondition(ConditionalOnCloudPlatform.class);
|
||||||
|
if (cloudPlatform.isActive(environment)) {
|
||||||
|
return ConditionOutcome.match(message.foundExactly(name));
|
||||||
|
}
|
||||||
|
return ConditionOutcome.noMatch(message.didNotFind(name).atAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2016 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.condition;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.cloud.CloudPlatform;
|
||||||
|
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link ConditionalOnCloudPlatform}.
|
||||||
|
*/
|
||||||
|
public class ConditionalOnCloudPlatformTests {
|
||||||
|
|
||||||
|
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void outcomeWhenCloudfoundryPlatformNotPresentShouldNotMatch()
|
||||||
|
throws Exception {
|
||||||
|
load(CloudFoundryPlatformConfig.class, "");
|
||||||
|
assertThat(this.context.containsBean("foo")).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void outcomeWhenCloudfoundryPlatformPresentShouldMatch() throws Exception {
|
||||||
|
load(CloudFoundryPlatformConfig.class, "VCAP_APPLICATION:---");
|
||||||
|
assertThat(this.context.containsBean("foo")).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void outcomeWhenCloudfoundryPlatformPresentAndMethodTargetShouldMatch()
|
||||||
|
throws Exception {
|
||||||
|
load(CloudFoundryPlatformOnMethodConfig.class, "VCAP_APPLICATION:---");
|
||||||
|
assertThat(this.context.containsBean("foo")).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void load(Class<?> config, String... environment) {
|
||||||
|
EnvironmentTestUtils.addEnvironment(this.context, environment);
|
||||||
|
this.context.register(config);
|
||||||
|
this.context.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY)
|
||||||
|
static class CloudFoundryPlatformConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public String foo() {
|
||||||
|
return "foo";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class CloudFoundryPlatformOnMethodConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY)
|
||||||
|
public String foo() {
|
||||||
|
return "foo";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue