diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfiguration.java index ebce6a5877e5..174b02af599c 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -51,8 +51,8 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration; import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration; @@ -84,6 +84,7 @@ * @author Dave Syer * @author Phillip Webb * @author Christian Dupuis + * @author Andy Wilkinson */ @Configuration @ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) @@ -155,14 +156,14 @@ public MvcEndpoints mvcEndpoints() { @Bean @ConditionalOnBean(EnvironmentEndpoint.class) - @ConditionalOnProperty(prefix = "endpoints.env", name = "enabled", matchIfMissing = true) + @ConditionalOnExpression("${endpoints.env.enabled:${endpoints.enabled:true}}") public EnvironmentMvcEndpoint environmentMvcEndpoint(EnvironmentEndpoint delegate) { return new EnvironmentMvcEndpoint(delegate); } @Bean @ConditionalOnBean(HealthEndpoint.class) - @ConditionalOnProperty(prefix = "endpoints.health", name = "enabled", matchIfMissing = true) + @ConditionalOnExpression("${endpoints.health.enabled:${endpoints.enabled:true}}") public HealthMvcEndpoint healthMvcEndpoint(HealthEndpoint delegate) { Security security = this.managementServerProperties.getSecurity(); boolean secure = (security == null || security.isEnabled()); @@ -176,14 +177,14 @@ public HealthMvcEndpoint healthMvcEndpoint(HealthEndpoint delegate) { @Bean @ConditionalOnBean(MetricsEndpoint.class) - @ConditionalOnProperty(prefix = "endpoints.metrics", name = "enabled", matchIfMissing = true) + @ConditionalOnExpression("${endpoints.metrics.enabled:${endpoints.enabled:true}}") public MetricsMvcEndpoint metricsMvcEndpoint(MetricsEndpoint delegate) { return new MetricsMvcEndpoint(delegate); } @Bean @ConditionalOnBean(ShutdownEndpoint.class) - @ConditionalOnProperty(prefix = "endpoints.shutdown", name = "enabled", matchIfMissing = true) + @ConditionalOnExpression("${endpoints.shutdown.enabled:false}") public ShutdownMvcEndpoint shutdownMvcEndpoint(ShutdownEndpoint delegate) { return new ShutdownMvcEndpoint(delegate); } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfiguration.java index da6a6c7cedce..3cfe63c42f45 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2015 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,8 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -39,8 +39,8 @@ * *

* This configuration will get automatically enabled as soon as the Jolokia - * {@link AgentServlet} is on the classpath. To disable set - * endpoints.jolokia.enabled: false. + * {@link AgentServlet} is on the classpath. To disable it set + * endpoints.jolokia.enabled: false or endpoints.enabled: false. * *

* Additional configuration parameters for Jolokia can be provided by specifying @@ -50,11 +50,12 @@ * * @author Christian Dupuis * @author Dave Syer + * @author Andy Wilkinson */ @Configuration @ConditionalOnWebApplication @ConditionalOnClass({ AgentServlet.class }) -@ConditionalOnProperty(prefix = "endpoints.jolokia", name = "enabled", matchIfMissing = true) +@ConditionalOnExpression("${endpoints.jolokia.enabled:${endpoints.enabled:true}}") @AutoConfigureBefore(ManagementSecurityAutoConfiguration.class) @AutoConfigureAfter(EmbeddedServletContainerAutoConfiguration.class) @EnableConfigurationProperties(JolokiaProperties.class) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointMvcAdapter.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointMvcAdapter.java index dc70c2d09740..e6159326a206 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointMvcAdapter.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointMvcAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -31,9 +31,14 @@ * Adapter class to expose {@link Endpoint}s as {@link MvcEndpoint}s. * * @author Dave Syer + * @author Andy Wilkinson */ public class EndpointMvcAdapter implements MvcEndpoint { + private final ResponseEntity> disabledResponse = new ResponseEntity>( + Collections.singletonMap("message", "This endpoint is disabled"), + HttpStatus.NOT_FOUND); + private final Endpoint delegate; /** @@ -49,9 +54,9 @@ public EndpointMvcAdapter(Endpoint delegate) { @ResponseBody public Object invoke() { if (!this.delegate.isEnabled()) { - // Shouldn't happen - return new ResponseEntity>(Collections.singletonMap( - "message", "This endpoint is disabled"), HttpStatus.NOT_FOUND); + // Shouldn't happen - MVC endpoint shouldn't be registered when delegate's + // disabled + return this.disabledResponse; } return this.delegate.invoke(); } @@ -76,4 +81,15 @@ public Class getEndpointType() { return this.delegate.getClass(); } + /** + * Returns the response that should be returned when the endpoint is disabled. + * + * @see Endpoint#isEnabled() + * @since 1.2.4 + * @return The response to be returned when the endpoint is disabled + */ + protected ResponseEntity getDisabledResponse() { + return this.disabledResponse; + } + } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EnvironmentMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EnvironmentMvcEndpoint.java index 28e34f0803cd..3915131dedb2 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EnvironmentMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EnvironmentMvcEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -31,6 +31,7 @@ * * @author Dave Syer * @author Christian Dupuis + * @author Andy Wilkinson */ public class EnvironmentMvcEndpoint extends EndpointMvcAdapter implements EnvironmentAware { @@ -44,6 +45,11 @@ public EnvironmentMvcEndpoint(EnvironmentEndpoint delegate) { @RequestMapping(value = "/{name:.*}", method = RequestMethod.GET) @ResponseBody public Object value(@PathVariable String name) { + if (!getDelegate().isEnabled()) { + // Shouldn't happen - MVC endpoint shouldn't be registered when delegate's + // disabled + return getDisabledResponse(); + } String result = this.environment.getProperty(name); if (result == null) { throw new NoSuchPropertyException("No such property: " + name); diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MetricsMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MetricsMvcEndpoint.java index eb9b951daa19..3aeb75964692 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MetricsMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/MetricsMvcEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -28,6 +28,7 @@ * Adapter to expose {@link MetricsEndpoint} as an {@link MvcEndpoint}. * * @author Dave Syer + * @author Andy Wilkinson */ public class MetricsMvcEndpoint extends EndpointMvcAdapter { @@ -41,6 +42,11 @@ public MetricsMvcEndpoint(MetricsEndpoint delegate) { @RequestMapping(value = "/{name:.*}", method = RequestMethod.GET) @ResponseBody public Object value(@PathVariable String name) { + if (!this.delegate.isEnabled()) { + // Shouldn't happen - MVC endpoint shouldn't be registered when delegate's + // disabled + return getDisabledResponse(); + } Object value = this.delegate.invoke().get(name); if (value == null) { throw new NoSuchMetricException("No such metric: " + name); diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java index fdc950ef8d04..73dab07bab3c 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -31,7 +31,11 @@ import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping; import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMappingCustomizer; +import org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint; +import org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint; +import org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint; import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; +import org.springframework.boot.actuate.endpoint.mvc.ShutdownMvcEndpoint; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration; import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration; @@ -67,6 +71,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertEquals; @@ -79,6 +84,7 @@ * * @author Phillip Webb * @author Greg Turnquist + * @author Andy Wilkinson */ public class EndpointWebMvcAutoConfigurationTests { @@ -100,8 +106,9 @@ public void close() { @Test public void onSamePort() throws Exception { - this.applicationContext.register(RootConfig.class, BaseConfiguration.class, - ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class); + this.applicationContext.register(RootConfig.class, EndpointConfig.class, + BaseConfiguration.class, ServerPortConfig.class, + EndpointWebMvcAutoConfiguration.class); this.applicationContext.refresh(); assertContent("/controller", ports.get().server, "controlleroutput"); assertContent("/endpoint", ports.get().server, "endpointoutput"); @@ -116,8 +123,9 @@ public void onSamePort() throws Exception { public void onSamePortWithoutHeader() throws Exception { EnvironmentTestUtils.addEnvironment(this.applicationContext, "management.add-application-context-header:false"); - this.applicationContext.register(RootConfig.class, BaseConfiguration.class, - ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class); + this.applicationContext.register(RootConfig.class, EndpointConfig.class, + BaseConfiguration.class, ServerPortConfig.class, + EndpointWebMvcAutoConfiguration.class); this.applicationContext.refresh(); assertFalse(hasHeader("/endpoint", ports.get().server, "X-Application-Context")); this.applicationContext.close(); @@ -126,9 +134,9 @@ public void onSamePortWithoutHeader() throws Exception { @Test public void onDifferentPort() throws Exception { - this.applicationContext.register(RootConfig.class, DifferentPortConfig.class, - BaseConfiguration.class, EndpointWebMvcAutoConfiguration.class, - ErrorMvcAutoConfiguration.class); + this.applicationContext.register(RootConfig.class, EndpointConfig.class, + DifferentPortConfig.class, BaseConfiguration.class, + EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class); this.applicationContext.refresh(); assertContent("/controller", ports.get().server, "controlleroutput"); assertContent("/endpoint", ports.get().server, null); @@ -144,9 +152,9 @@ public void onDifferentPort() throws Exception { @Test public void onRandomPort() throws Exception { - this.applicationContext.register(RootConfig.class, RandomPortConfig.class, - BaseConfiguration.class, EndpointWebMvcAutoConfiguration.class, - ErrorMvcAutoConfiguration.class); + this.applicationContext.register(RootConfig.class, EndpointConfig.class, + RandomPortConfig.class, BaseConfiguration.class, + EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class); GrabManagementPort grabManagementPort = new GrabManagementPort( this.applicationContext); this.applicationContext.addApplicationListener(grabManagementPort); @@ -161,8 +169,9 @@ public void onRandomPort() throws Exception { @Test public void disabled() throws Exception { - this.applicationContext.register(RootConfig.class, DisableConfig.class, - BaseConfiguration.class, EndpointWebMvcAutoConfiguration.class); + this.applicationContext.register(RootConfig.class, EndpointConfig.class, + DisableConfig.class, BaseConfiguration.class, + EndpointWebMvcAutoConfiguration.class); this.applicationContext.refresh(); assertContent("/controller", ports.get().server, "controlleroutput"); assertContent("/endpoint", ports.get().server, null); @@ -176,8 +185,9 @@ public void disabled() throws Exception { public void specificPortsViaProperties() throws Exception { EnvironmentTestUtils.addEnvironment(this.applicationContext, "server.port:" + ports.get().server, "management.port:" + ports.get().management); - this.applicationContext.register(RootConfig.class, BaseConfiguration.class, - EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class); + this.applicationContext.register(RootConfig.class, EndpointConfig.class, + BaseConfiguration.class, EndpointWebMvcAutoConfiguration.class, + ErrorMvcAutoConfiguration.class); this.applicationContext.refresh(); assertContent("/controller", ports.get().server, "controlleroutput"); assertContent("/endpoint", ports.get().server, null); @@ -191,8 +201,8 @@ public void specificPortsViaProperties() throws Exception { public void contextPath() throws Exception { EnvironmentTestUtils.addEnvironment(this.applicationContext, "management.contextPath:/test"); - this.applicationContext.register(RootConfig.class, ServerPortConfig.class, - PropertyPlaceholderAutoConfiguration.class, + this.applicationContext.register(RootConfig.class, EndpointConfig.class, + ServerPortConfig.class, PropertyPlaceholderAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class, ServerPropertiesAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class, @@ -255,6 +265,88 @@ public void singleRequestMappingInfoHandlerMappingBean() throws Exception { assertThat(mapping, not(instanceOf(EndpointHandlerMapping.class))); } + @Test + public void endpointsDefaultConfiguration() throws Exception { + this.applicationContext.register(RootConfig.class, BaseConfiguration.class, + ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class); + this.applicationContext.refresh(); + // /health, /metrics, /env (/shutdown is disabled by default) + assertThat(this.applicationContext.getBeansOfType(MvcEndpoint.class).size(), + is(equalTo(3))); + } + + @Test + public void endpointsAllDisabled() throws Exception { + this.applicationContext.register(RootConfig.class, BaseConfiguration.class, + ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.applicationContext, + "endpoints.enabled:false"); + this.applicationContext.refresh(); + assertThat(this.applicationContext.getBeansOfType(MvcEndpoint.class).size(), + is(equalTo(0))); + } + + @Test + public void environmentEndpointDisabled() throws Exception { + endpointDisabled("env", EnvironmentMvcEndpoint.class); + } + + @Test + public void environmentEndpointEnabledOverride() throws Exception { + endpointEnabledOverride("env", EnvironmentMvcEndpoint.class); + } + + @Test + public void metricsEndpointDisabled() throws Exception { + endpointDisabled("metrics", MetricsMvcEndpoint.class); + } + + @Test + public void metricsEndpointEnabledOverride() throws Exception { + endpointEnabledOverride("metrics", MetricsMvcEndpoint.class); + } + + @Test + public void healthEndpointDisabled() throws Exception { + endpointDisabled("health", HealthMvcEndpoint.class); + } + + @Test + public void healthEndpointEnabledOverride() throws Exception { + endpointEnabledOverride("health", HealthMvcEndpoint.class); + } + + @Test + public void shutdownEndpointEnabled() { + this.applicationContext.register(RootConfig.class, BaseConfiguration.class, + ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.applicationContext, + "endpoints.shutdown.enabled:true"); + this.applicationContext.refresh(); + assertThat(this.applicationContext.getBeansOfType(ShutdownMvcEndpoint.class) + .size(), is(equalTo(1))); + } + + private void endpointDisabled(String name, Class type) { + this.applicationContext.register(RootConfig.class, BaseConfiguration.class, + ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.applicationContext, + String.format("endpoints.%s.enabled:false", name)); + this.applicationContext.refresh(); + assertThat(this.applicationContext.getBeansOfType(type).size(), is(equalTo(0))); + } + + private void endpointEnabledOverride(String name, Class type) + throws Exception { + this.applicationContext.register(RootConfig.class, BaseConfiguration.class, + ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.applicationContext, + "endpoints.enabled:false", + String.format("endpoints.%s.enabled:true", name)); + this.applicationContext.refresh(); + assertThat(this.applicationContext.getBeansOfType(type).size(), is(equalTo(1))); + } + private void assertAllClosed() throws Exception { assertContent("/controller", ports.get().server, null); assertContent("/endpoint", ports.get().server, null); @@ -307,6 +399,7 @@ private static class Ports { @Configuration @Import({ PropertyPlaceholderAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class, + EndpointAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class, @@ -323,6 +416,11 @@ public TestController testController() { return new TestController(); } + } + + @Configuration + public static class EndpointConfig { + @Bean public TestEndpoint testEndpoint() { return new TestEndpoint(); diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfigurationTests.java index 5ac1d76aad89..dae25a2d46b2 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/JolokiaAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2015 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,7 @@ * Tests for {@link JolokiaAutoConfiguration}. * * @author Christian Dupuis + * @author Andy Wilkinson */ public class JolokiaAutoConfigurationTests { @@ -67,10 +68,23 @@ public void agentServletRegisteredWithAppContext() throws Exception { } @Test - public void agentDisabled() throws Exception { + public void endpointDisabled() throws Exception { + assertEndpointDisabled("endpoints.jolokia.enabled:false"); + } + + @Test + public void allEndpointsDisabled() throws Exception { + assertEndpointDisabled("endpoints.enabled:false"); + } + + @Test + public void endpointEnabledAsOverride() throws Exception { + assertEndpointEnabled("endpoints.enabled:false", "endpoints.jolokia.enabled:true"); + } + + private void assertEndpointDisabled(String... pairs) { this.context = new AnnotationConfigEmbeddedWebApplicationContext(); - EnvironmentTestUtils.addEnvironment(this.context, - "endpoints.jolokia.enabled:false"); + EnvironmentTestUtils.addEnvironment(this.context, pairs); this.context.register(Config.class, WebMvcAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class, @@ -80,6 +94,18 @@ public void agentDisabled() throws Exception { assertEquals(0, this.context.getBeanNamesForType(JolokiaMvcEndpoint.class).length); } + private void assertEndpointEnabled(String... pairs) { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, pairs); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, + ManagementServerPropertiesAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + JolokiaAutoConfiguration.class); + this.context.refresh(); + assertEquals(1, this.context.getBeanNamesForType(JolokiaMvcEndpoint.class).length); + } + @Configuration @EnableConfigurationProperties protected static class Config { diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/EnvironmentMvcEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/EnvironmentMvcEndpointTests.java index 7ef5a5defb54..fa1f71dd1632 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/EnvironmentMvcEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/EnvironmentMvcEndpointTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2015 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. @@ -44,7 +44,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** + * Tests for {@link EnvironmentMvcEndpoint} + * * @author Dave Syer + * @author Andy Wilkinson */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = { TestConfiguration.class }) @@ -58,6 +61,7 @@ public class EnvironmentMvcEndpointTests { @Before public void setUp() { + this.context.getBean(EnvironmentEndpoint.class).setEnabled(true); this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); EnvironmentTestUtils.addEnvironment( (ConfigurableApplicationContext) this.context, "foo:bar"); @@ -75,6 +79,12 @@ public void sub() throws Exception { .andExpect(content().string(equalToIgnoringCase("bar"))); } + @Test + public void subWhenDisabled() throws Exception { + this.context.getBean(EnvironmentEndpoint.class).setEnabled(false); + this.mvc.perform(get("/env/foo")).andExpect(status().isNotFound()); + } + @Import({ EndpointWebMvcAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class }) @EnableWebMvc diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaEndpointContextPathTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpointContextPathTests.java similarity index 91% rename from spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaEndpointContextPathTests.java rename to spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpointContextPathTests.java index 00fcedaf26c5..f50fb4f05c19 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaEndpointContextPathTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpointContextPathTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2015 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. @@ -23,8 +23,8 @@ import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration; -import org.springframework.boot.actuate.endpoint.mvc.JolokiaEndpointContextPathTests.Config; -import org.springframework.boot.actuate.endpoint.mvc.JolokiaEndpointContextPathTests.ContextPathListener; +import org.springframework.boot.actuate.endpoint.mvc.JolokiaMvcEndpointContextPathTests.Config; +import org.springframework.boot.actuate.endpoint.mvc.JolokiaMvcEndpointContextPathTests.ContextPathListener; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.boot.test.SpringApplicationConfiguration; @@ -51,7 +51,7 @@ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = { Config.class }, initializers = ContextPathListener.class) @WebAppConfiguration -public class JolokiaEndpointContextPathTests { +public class JolokiaMvcEndpointContextPathTests { @Autowired private MvcEndpoints endpoints; diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpointTests.java similarity index 94% rename from spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaEndpointTests.java rename to spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpointTests.java index 952523073e08..9b02bb663c17 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/JolokiaMvcEndpointTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2015 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,7 +25,7 @@ import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration; -import org.springframework.boot.actuate.endpoint.mvc.JolokiaEndpointTests.Config; +import org.springframework.boot.actuate.endpoint.mvc.JolokiaMvcEndpointTests.Config; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.boot.test.SpringApplicationConfiguration; @@ -47,13 +47,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** + * Tests for {@link JolokiaMvcEndpoint} + * * @author Christian Dupuis * @author Dave Syer */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = { Config.class }) @WebAppConfiguration -public class JolokiaEndpointTests { +public class JolokiaMvcEndpointTests { @Autowired private MvcEndpoints endpoints; @@ -103,5 +105,7 @@ public void list() throws Exception { @Import({ EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class, ManagementServerPropertiesAutoConfiguration.class }) public static class Config { + } + } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/MetricsMvcEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/MetricsMvcEndpointTests.java new file mode 100644 index 000000000000..fc50083c2908 --- /dev/null +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/MetricsMvcEndpointTests.java @@ -0,0 +1,124 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.mvc; + +import java.util.Arrays; +import java.util.Collection; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +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.MetricsEndpoint; +import org.springframework.boot.actuate.endpoint.PublicMetrics; +import org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpointTests.TestConfiguration; +import org.springframework.boot.actuate.metrics.Metric; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +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.status; + +/** + * Tests for {@link MetricsMvcEndpoint} + * + * @author Andy Wilkinson + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = { TestConfiguration.class }) +@WebAppConfiguration +public class MetricsMvcEndpointTests { + + @Autowired + private WebApplicationContext context; + + private MockMvc mvc; + + @Before + public void setUp() { + this.context.getBean(MetricsEndpoint.class).setEnabled(true); + this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); + } + + @Test + public void home() throws Exception { + this.mvc.perform(get("/metrics")).andExpect(status().isOk()) + .andExpect(content().string(containsString("\"foo\":1"))); + } + + @Test + public void homeWhenDisabled() throws Exception { + this.context.getBean(MetricsEndpoint.class).setEnabled(false); + this.mvc.perform(get("/metrics")).andExpect(status().isNotFound()); + } + + @Test + public void specificMetric() throws Exception { + this.mvc.perform(get("/metrics/foo")).andExpect(status().isOk()) + .andExpect(content().string(equalTo("1"))); + } + + @Test + public void specificMetricWhenDisabled() throws Exception { + this.context.getBean(MetricsEndpoint.class).setEnabled(false); + this.mvc.perform(get("/metrics/foo")).andExpect(status().isNotFound()); + } + + @Test + public void specificMetricThatDoesNotExist() throws Exception { + this.mvc.perform(get("/metrics/bar")).andExpect(status().isNotFound()); + } + + @Import({ EndpointWebMvcAutoConfiguration.class, + ManagementServerPropertiesAutoConfiguration.class }) + @EnableWebMvc + @Configuration + public static class TestConfiguration { + + @Bean + public MetricsEndpoint endpoint() { + return new MetricsEndpoint(new PublicMetrics() { + + @Override + public Collection> metrics() { + return Arrays.> asList(new Metric("foo", 1)); + } + + }); + } + + @Bean + public MetricsMvcEndpoint mvcEndpoint() { + return new MetricsMvcEndpoint(endpoint()); + } + + } + +}