Merge branch '1.5.x'

pull/3254/merge
Phillip Webb 8 years ago
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,33 +115,44 @@ 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); if (handler instanceof String) {
String prefix = StringUtils.hasText(this.prefix) ? this.prefix + path : path; handler = getApplicationContext().getBean((String) handler);
}
Assert.state(handler instanceof MvcEndpoint, "Only MvcEndpoints are supported");
String path = getPath((MvcEndpoint) handler);
return (path == null ? null : getEndpointPatterns(path, mapping));
}
/**
* 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(); Set<String> defaultPatterns = mapping.getPatternsCondition().getPatterns();
if (defaultPatterns.isEmpty()) { if (defaultPatterns.isEmpty()) {
return new String[] { prefix, prefix + ".json" }; return new String[] { patternPrefix, patternPrefix + ".json" };
} }
List<String> patterns = new ArrayList<String>(defaultPatterns); List<String> patterns = new ArrayList<String>(defaultPatterns);
for (int i = 0; i < patterns.size(); i++) { for (int i = 0; i < patterns.size(); i++) {
patterns.set(i, prefix + patterns.get(i)); patterns.set(i, patternPrefix + patterns.get(i));
} }
return patterns.toArray(new String[patterns.size()]); return patterns.toArray(new String[patterns.size()]);
} }
private String getPath(Object handler) {
if (handler instanceof String) {
handler = getApplicationContext().getBean((String) handler);
}
if (handler instanceof MvcEndpoint) {
return ((MvcEndpoint) handler).getPath();
}
return "";
}
private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping, private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping,
String[] patternStrings) { String[] patternStrings) {
PatternsRequestCondition patterns = new PatternsRequestCondition(patternStrings, PatternsRequestCondition patterns = new PatternsRequestCondition(patternStrings,
@ -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…
Cancel
Save