diff --git a/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/resources/application.properties b/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/resources/application.properties index 437acb0b81a..c7fe96e1cf4 100644 --- a/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/resources/application.properties +++ b/spring-bootstrap-samples/spring-bootstrap-service-sample/src/main/resources/application.properties @@ -1,8 +1,8 @@ logging.file: /tmp/logs/app.log -container.port: 8080 -container.management_port: 8080 -container.allow_shutdown: true -container.tomcat.basedir: target/tomcat -container.tomcat.access_log_pattern: %h %t "%r" %s %b +management.port: 8080 +management.allow_shutdown: true +server.port: 8080 +server.tomcat.basedir: target/tomcat +server.tomcat.access_log_pattern: %h %t "%r" %s %b security.require_ssl: false service.name: Phil \ No newline at end of file diff --git a/spring-bootstrap-samples/spring-bootstrap-service-sample/src/test/java/org/springframework/bootstrap/sample/service/NoVarzContextServiceBootstrapApplicationTests.java b/spring-bootstrap-samples/spring-bootstrap-service-sample/src/test/java/org/springframework/bootstrap/sample/service/NoVarzContextServiceBootstrapApplicationTests.java new file mode 100644 index 00000000000..f7fcc35f9ef --- /dev/null +++ b/spring-bootstrap-samples/spring-bootstrap-service-sample/src/test/java/org/springframework/bootstrap/sample/service/NoVarzContextServiceBootstrapApplicationTests.java @@ -0,0 +1,120 @@ +package org.springframework.bootstrap.sample.service; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.bootstrap.SpringApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.http.HttpRequest; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.http.client.InterceptingClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.ResourceAccessException; +import org.springframework.web.client.RestTemplate; + +import static org.junit.Assert.assertEquals; + +/** + * Integration tests for switching off management endpoints. + * + * @author Dave Syer + * + */ +public class NoVarzContextServiceBootstrapApplicationTests { + + private static ConfigurableApplicationContext context; + + private static int managementPort = 0; + + @BeforeClass + public static void start() throws Exception { + final String[] args = new String[] { "--management.port=" + managementPort }; + Future future = Executors + .newSingleThreadExecutor().submit( + new Callable() { + @Override + public ConfigurableApplicationContext call() throws Exception { + return (ConfigurableApplicationContext) SpringApplication + .run(ServiceBootstrapApplication.class, args); + } + }); + context = future.get(10, TimeUnit.SECONDS); + } + + @AfterClass + public static void stop() { + if (context != null) { + context.close(); + } + } + + @Test + public void testHome() throws Exception { + @SuppressWarnings("rawtypes") + ResponseEntity entity = getRestTemplate("user", "password").getForEntity( + "http://localhost:8080", Map.class); + assertEquals(HttpStatus.OK, entity.getStatusCode()); + @SuppressWarnings("unchecked") + Map body = entity.getBody(); + assertEquals("Hello Phil", body.get("message")); + } + + @Test(expected = ResourceAccessException.class) + public void testVarzNotAvailable() throws Exception { + testHome(); // makes sure some requests have been made + @SuppressWarnings("rawtypes") + ResponseEntity entity = getRestTemplate("user", "password").getForEntity( + "http://localhost:" + managementPort + "/varz", Map.class); + assertEquals(HttpStatus.NOT_FOUND, entity.getStatusCode()); + } + + private RestTemplate getRestTemplate(final String username, final String password) { + + List interceptors = new ArrayList(); + + if (username != null) { + + interceptors.add(new ClientHttpRequestInterceptor() { + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, + ClientHttpRequestExecution execution) throws IOException { + request.getHeaders().add( + "Authorization", + "Basic " + + new String(Base64 + .encode((username + ":" + password) + .getBytes()))); + return execution.execute(request, body); + } + }); + } + + RestTemplate restTemplate = new RestTemplate( + new InterceptingClientHttpRequestFactory( + new SimpleClientHttpRequestFactory(), interceptors)); + restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { + @Override + public void handleError(ClientHttpResponse response) throws IOException { + } + }); + return restTemplate; + + } + +} diff --git a/spring-bootstrap-samples/spring-bootstrap-service-sample/src/test/java/org/springframework/bootstrap/sample/service/VarzContextServiceBootstrapApplicationTests.java b/spring-bootstrap-samples/spring-bootstrap-service-sample/src/test/java/org/springframework/bootstrap/sample/service/VarzContextServiceBootstrapApplicationTests.java index 9b06c001643..f1f390546c5 100644 --- a/spring-bootstrap-samples/spring-bootstrap-service-sample/src/test/java/org/springframework/bootstrap/sample/service/VarzContextServiceBootstrapApplicationTests.java +++ b/spring-bootstrap-samples/spring-bootstrap-service-sample/src/test/java/org/springframework/bootstrap/sample/service/VarzContextServiceBootstrapApplicationTests.java @@ -44,8 +44,8 @@ public class VarzContextServiceBootstrapApplicationTests { @BeforeClass public static void start() throws Exception { - final String[] args = new String[] { "--container.port=" + port, - "--container.management_port=" + managementPort }; + final String[] args = new String[] { "--server.port=" + port, + "--management.port=" + managementPort }; Future future = Executors .newSingleThreadExecutor().submit( new Callable() { diff --git a/spring-bootstrap-samples/spring-bootstrap-service-sample/start.groovy b/spring-bootstrap-samples/spring-bootstrap-service-sample/start.groovy new file mode 100644 index 00000000000..53719fc6013 --- /dev/null +++ b/spring-bootstrap-samples/spring-bootstrap-service-sample/start.groovy @@ -0,0 +1,4 @@ +@Configuration +@Import(org.springframework.bootstrap.sample.service.ServiceBootstrapApplication) +class Start { +} \ No newline at end of file diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/HealthzAutoConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/HealthzConfiguration.java similarity index 97% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/HealthzAutoConfiguration.java rename to spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/HealthzConfiguration.java index dae2b33cee4..c21d3c066aa 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/HealthzAutoConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/HealthzConfiguration.java @@ -37,7 +37,7 @@ import org.springframework.web.servlet.DispatcherServlet; @Configuration @ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) @ConditionalOnMissingBean({ HealthzEndpoint.class }) -public class HealthzAutoConfiguration { +public class HealthzConfiguration { @Autowired(required = false) private HealthIndicator healthIndicator = new VanillaHealthIndicator(); diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementAutoConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementConfiguration.java similarity index 70% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementAutoConfiguration.java rename to spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementConfiguration.java index fe77d1ac7a6..0f569124c8a 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementAutoConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementConfiguration.java @@ -20,7 +20,8 @@ import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.bootstrap.context.annotation.ConditionalOnExpression; import org.springframework.bootstrap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext; -import org.springframework.bootstrap.service.properties.ContainerProperties; +import org.springframework.bootstrap.service.properties.ManagementServerProperties; +import org.springframework.bootstrap.service.properties.ServerProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationListener; @@ -34,19 +35,23 @@ import org.springframework.context.event.ContextRefreshedEvent; * */ @Configuration -public class ManagementAutoConfiguration implements ApplicationContextAware, - DisposableBean, ApplicationListener { +@ConditionalOnExpression("${management.port:8080}>0") +public class ManagementConfiguration implements ApplicationContextAware, DisposableBean, + ApplicationListener { private ApplicationContext parent; private ConfigurableApplicationContext context; @Autowired - private ContainerProperties configuration = new ContainerProperties(); + private ServerProperties configuration = new ServerProperties(); - @ConditionalOnExpression("${container.port:8080} == ${container.management_port:8080}") + @Autowired + private ManagementServerProperties management = new ManagementServerProperties(); + + @ConditionalOnExpression("${server.port:8080} == ${management.port:8080}") @Configuration - @Import({ VarzAutoConfiguration.class, HealthzAutoConfiguration.class, - ShutdownAutoConfiguration.class, TraceAutoConfiguration.class }) + @Import({ VarzConfiguration.class, HealthzConfiguration.class, + ShutdownConfiguration.class, TraceConfiguration.class }) public static class ManagementEndpointsConfiguration { } @@ -68,12 +73,12 @@ public class ManagementAutoConfiguration implements ApplicationContextAware, if (event.getSource() != this.parent) { return; } - if (this.configuration.getPort() != this.configuration.getManagementPort()) { + if (this.configuration.getPort() != this.management.getPort()) { AnnotationConfigEmbeddedWebApplicationContext context = new AnnotationConfigEmbeddedWebApplicationContext(); context.setParent(this.parent); - context.register(ManagementContainerConfiguration.class, - VarzAutoConfiguration.class, HealthzAutoConfiguration.class, - ShutdownAutoConfiguration.class, TraceAutoConfiguration.class); + context.register(ManagementServerConfiguration.class, + VarzConfiguration.class, HealthzConfiguration.class, + ShutdownConfiguration.class, TraceConfiguration.class); context.refresh(); this.context = context; } diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementContainerConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementServerConfiguration.java similarity index 92% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementContainerConfiguration.java rename to spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementServerConfiguration.java index ba465c114ae..8b3c9c10676 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementContainerConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ManagementServerConfiguration.java @@ -30,7 +30,7 @@ import org.springframework.bootstrap.context.embedded.ErrorPage; import org.springframework.bootstrap.context.embedded.jetty.JettyEmbeddedServletContainerFactory; import org.springframework.bootstrap.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.bootstrap.service.error.ErrorEndpoint; -import org.springframework.bootstrap.service.properties.ContainerProperties; +import org.springframework.bootstrap.service.properties.ManagementServerProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -45,10 +45,10 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc; */ @Configuration @EnableWebMvc -public class ManagementContainerConfiguration implements BeanPostProcessor { +public class ManagementServerConfiguration implements BeanPostProcessor { @Autowired - private ContainerProperties configuration = new ContainerProperties(); + private ManagementServerProperties configuration = new ManagementServerProperties(); private boolean initialized = false; @@ -103,7 +103,7 @@ public class ManagementContainerConfiguration implements BeanPostProcessor { && !this.initialized) { AbstractEmbeddedServletContainerFactory factory = (AbstractEmbeddedServletContainerFactory) bean; - factory.setPort(this.configuration.getManagementPort()); + factory.setPort(this.configuration.getPort()); factory.setContextPath(this.configuration.getContextPath()); factory.setErrorPages(Collections diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricAutoConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricConfiguration.java similarity index 98% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricAutoConfiguration.java rename to spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricConfiguration.java index ade6b27f6ae..0a534234f43 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricAutoConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricConfiguration.java @@ -33,7 +33,7 @@ import org.springframework.context.annotation.Configuration; * */ @Configuration -public class MetricAutoConfiguration { +public class MetricConfiguration { @Bean @ConditionalOnMissingBean({ CounterService.class }) diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricFilterAutoConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricFilterConfiguration.java similarity index 90% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricFilterAutoConfiguration.java rename to spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricFilterConfiguration.java index aed0ecda1ee..194fc2f4418 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricFilterAutoConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/MetricFilterConfiguration.java @@ -50,7 +50,7 @@ import org.springframework.web.util.UrlPathHelper; // FIXME: make this conditional // @ConditionalOnBean({ CounterService.class, GaugeService.class }) @ConditionalOnClass({ Servlet.class }) -public class MetricFilterAutoConfiguration { +public class MetricFilterConfiguration { @Autowired(required = false) private CounterService counterService; @@ -84,24 +84,28 @@ public class MetricFilterAutoConfiguration { DateTime t0 = new DateTime(); try { chain.doFilter(request, response); - status = servletResponse.getStatus(); } finally { + try { + status = servletResponse.getStatus(); + } catch (Exception e) { + // ignore + } set("response", suffix, new Duration(t0, new DateTime()).getMillis()); increment("status." + status, suffix); } } private void increment(String prefix, String suffix) { - if (MetricFilterAutoConfiguration.this.counterService != null) { + if (MetricFilterConfiguration.this.counterService != null) { String key = getKey(prefix + suffix); - MetricFilterAutoConfiguration.this.counterService.increment(key); + MetricFilterConfiguration.this.counterService.increment(key); } } private void set(String prefix, String suffix, double value) { - if (MetricFilterAutoConfiguration.this.gaugeService != null) { + if (MetricFilterConfiguration.this.gaugeService != null) { String key = getKey(prefix + suffix); - MetricFilterAutoConfiguration.this.gaugeService.set(key, value); + MetricFilterConfiguration.this.gaugeService.set(key, value); } } diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/SecurityAutoConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/SecurityConfiguration.java similarity index 98% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/SecurityAutoConfiguration.java rename to spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/SecurityConfiguration.java index 18d07bce1f0..f2346bf7453 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/SecurityAutoConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/SecurityConfiguration.java @@ -42,7 +42,7 @@ import org.springframework.stereotype.Component; @ConditionalOnMissingBean({ WebSecurityConfiguration.class }) @EnableWebSecurity @EnableConfigurationProperties(SecurityProperties.class) -public class SecurityAutoConfiguration { +public class SecurityConfiguration { @Component public static class WebSecurityAdapter extends WebSecurityConfigurerAdapter { diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ContainerConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServerConfiguration.java similarity index 90% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ContainerConfiguration.java rename to spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServerConfiguration.java index ad58d67b3ef..675ba5a55e1 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ContainerConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServerConfiguration.java @@ -33,8 +33,8 @@ import org.springframework.bootstrap.context.embedded.EmbeddedServletContainerFa import org.springframework.bootstrap.context.embedded.ErrorPage; import org.springframework.bootstrap.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.bootstrap.service.error.ErrorEndpoint; -import org.springframework.bootstrap.service.properties.ContainerProperties; -import org.springframework.bootstrap.service.properties.ContainerProperties.Tomcat; +import org.springframework.bootstrap.service.properties.ServerProperties; +import org.springframework.bootstrap.service.properties.ServerProperties.Tomcat; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; @@ -45,12 +45,12 @@ import org.springframework.util.StringUtils; * * @author Dave Syer */ -// Slight hack here (BeanPostProcessor), to force the container properties to be bound in +// Slight hack here (BeanPostProcessor), to force the server properties to be bound in // the right order @Configuration @ConditionalOnClass({ Servlet.class }) @Order(Integer.MIN_VALUE) -public class ContainerConfiguration implements BeanPostProcessor, BeanFactoryAware { +public class ServerConfiguration implements BeanPostProcessor, BeanFactoryAware { private BeanFactory beanFactory; @@ -89,8 +89,8 @@ public class ContainerConfiguration implements BeanPostProcessor, BeanFactoryAwa && !this.initialized) { // Cannot use @Autowired because the injection happens too early - ContainerProperties configuration = this.beanFactory - .getBean(ContainerProperties.class); + ServerProperties configuration = this.beanFactory + .getBean(ServerProperties.class); AbstractEmbeddedServletContainerFactory factory = (AbstractEmbeddedServletContainerFactory) bean; factory.setPort(configuration.getPort()); @@ -114,7 +114,7 @@ public class ContainerConfiguration implements BeanPostProcessor, BeanFactoryAwa } private void configureTomcat(TomcatEmbeddedServletContainerFactory tomcatFactory, - ContainerProperties configuration) { + ServerProperties configuration) { Tomcat tomcat = configuration.getTomcat(); if (tomcat.getBasedir() != null) { diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServiceAutoConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServiceAutoConfiguration.java index 38c92108ce8..41fabf0d60f 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServiceAutoConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ServiceAutoConfiguration.java @@ -20,7 +20,8 @@ import java.util.List; import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration; import org.springframework.bootstrap.service.annotation.EnableConfigurationProperties; -import org.springframework.bootstrap.service.properties.ContainerProperties; +import org.springframework.bootstrap.service.properties.ManagementServerProperties; +import org.springframework.bootstrap.service.properties.ServerProperties; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.converter.HttpMessageConverter; @@ -36,9 +37,9 @@ import com.fasterxml.jackson.datatype.joda.JodaModule; * @author Dave Syer */ @Configuration -@Import({ ManagementAutoConfiguration.class, MetricAutoConfiguration.class, - ContainerConfiguration.class, SecurityAutoConfiguration.class, - MetricFilterAutoConfiguration.class }) +@Import({ ManagementConfiguration.class, MetricConfiguration.class, + ServerConfiguration.class, SecurityConfiguration.class, + MetricFilterConfiguration.class }) public class ServiceAutoConfiguration extends WebMvcConfigurationSupport { @Override @@ -55,11 +56,12 @@ public class ServiceAutoConfiguration extends WebMvcConfigurationSupport { } /* - * ContainerProperties has to be declared in a non-conditional bean, so that it gets + * ServerProperties has to be declared in a non-conditional bean, so that it gets * added to the context early enough */ - @EnableConfigurationProperties(ContainerProperties.class) - public static class ContainerPropertiesConfiguration { + @EnableConfigurationProperties({ ServerProperties.class, + ManagementServerProperties.class }) + public static class ServerPropertiesConfiguration { } } diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ShutdownAutoConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ShutdownConfiguration.java similarity index 97% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ShutdownAutoConfiguration.java rename to spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ShutdownConfiguration.java index 640218e6566..a288847bb52 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ShutdownAutoConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/ShutdownConfiguration.java @@ -34,7 +34,7 @@ import org.springframework.web.servlet.DispatcherServlet; @Configuration @ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) @ConditionalOnMissingBean({ ShutdownEndpoint.class }) -public class ShutdownAutoConfiguration { +public class ShutdownConfiguration { @Bean public ShutdownEndpoint shutdownEndpoint() { diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/TraceAutoConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/TraceConfiguration.java similarity index 86% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/TraceAutoConfiguration.java rename to spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/TraceConfiguration.java index 0cd89ae938b..b38275fd48c 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/TraceAutoConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/TraceConfiguration.java @@ -41,25 +41,25 @@ import org.springframework.web.servlet.DispatcherServlet; @Configuration @ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) @ConditionalOnMissingBean({ TraceEndpoint.class }) -public class TraceAutoConfiguration { +public class TraceConfiguration { - @Autowired(required = false) - private TraceRepository traceRepository = new InMemoryTraceRepository(); - - @Bean - @ConditionalOnMissingBean(TraceRepository.class) - protected TraceRepository traceRepository() { - return this.traceRepository; - } + @Autowired + private TraceRepository traceRepository; @Configuration @ConditionalOnClass(SecurityFilterChain.class) public static class SecurityFilterPostProcessorConfiguration { - @Autowired - private TraceRepository traceRepository; + @Autowired(required = false) + private TraceRepository traceRepository = new InMemoryTraceRepository(); - @Value("${container.dump_requests:false}") + @Bean + @ConditionalOnMissingBean(TraceRepository.class) + protected TraceRepository traceRepository() { + return this.traceRepository; + } + + @Value("${management.dump_requests:false}") private boolean dumpRequests; @Bean diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/VarzAutoConfiguration.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/VarzConfiguration.java similarity index 98% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/VarzAutoConfiguration.java rename to spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/VarzConfiguration.java index ac82365f57d..0357fb2bc0e 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/VarzAutoConfiguration.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/autoconfigure/service/VarzConfiguration.java @@ -38,7 +38,7 @@ import org.springframework.web.servlet.DispatcherServlet; @Configuration @ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) @ConditionalOnMissingBean({ VarzEndpoint.class }) -public class VarzAutoConfiguration { +public class VarzConfiguration { @Autowired private MetricRepository repository; diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/ConfigurationPropertiesImportSelector.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/ConfigurationPropertiesImportSelector.java index 99ecc9e7948..fb32f7adc6a 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/ConfigurationPropertiesImportSelector.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/ConfigurationPropertiesImportSelector.java @@ -16,6 +16,9 @@ package org.springframework.bootstrap.service.annotation; +import java.util.ArrayList; +import java.util.List; + import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.bootstrap.context.annotation.ConfigurationProperties; @@ -25,11 +28,13 @@ import org.springframework.core.type.AnnotationMetadata; import org.springframework.util.MultiValueMap; /** - * Import selector that sets up binding of external properties to configuration classes (see - * {@link ConfigurationProperties}). It either registers a {@link ConfigurationProperties} bean or not, depending on - * whether the enclosing {@link EnableConfigurationProperties} explicitly declares one. If none is declared then a bean - * post processor will still kick in for any beans annotated as external configuration. If one is declared then it a - * bean definition is registered with id equal to the class name (thus an application context usually only contains one + * Import selector that sets up binding of external properties to configuration classes + * (see {@link ConfigurationProperties}). It either registers a + * {@link ConfigurationProperties} bean or not, depending on whether the enclosing + * {@link EnableConfigurationProperties} explicitly declares one. If none is declared then + * a bean post processor will still kick in for any beans annotated as external + * configuration. If one is declared then it a bean definition is registered with id equal + * to the class name (thus an application context usually only contains one * {@link ConfigurationProperties} bean of each unique type). * * @author Dave Syer @@ -42,21 +47,39 @@ public class ConfigurationPropertiesImportSelector implements ImportSelector { EnableConfigurationProperties.class.getName(), false); Object type = attributes.getFirst("value"); if (type == void.class) { - return new String[] { ConfigurationPropertiesBindingConfiguration.class.getName() }; + return new String[] { ConfigurationPropertiesBindingConfiguration.class + .getName() }; } return new String[] { ConfigurationPropertiesBeanRegistrar.class.getName(), ConfigurationPropertiesBindingConfiguration.class.getName() }; } - public static class ConfigurationPropertiesBeanRegistrar implements ImportBeanDefinitionRegistrar { + public static class ConfigurationPropertiesBeanRegistrar implements + ImportBeanDefinitionRegistrar { @Override - public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { - MultiValueMap attributes = metadata.getAllAnnotationAttributes( - EnableConfigurationProperties.class.getName(), false); - Class type = (Class) attributes.getFirst("value"); - registry.registerBeanDefinition(type.getName(), BeanDefinitionBuilder.genericBeanDefinition(type) - .getBeanDefinition()); + public void registerBeanDefinitions(AnnotationMetadata metadata, + BeanDefinitionRegistry registry) { + MultiValueMap attributes = metadata + .getAllAnnotationAttributes( + EnableConfigurationProperties.class.getName(), false); + List> types = collectClasses(attributes.get("value")); + for (Class type : types) { + registry.registerBeanDefinition(type.getName(), BeanDefinitionBuilder + .genericBeanDefinition(type).getBeanDefinition()); + } + } + + private List> collectClasses(List list) { + ArrayList> result = new ArrayList>(); + for (Object object : list) { + for (Object value : (Object[]) object) { + if (value instanceof Class) { + result.add((Class) value); + } + } + } + return result; } } diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/EnableConfigurationProperties.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/EnableConfigurationProperties.java index 92e1455257d..64ddc4e16c0 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/EnableConfigurationProperties.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/annotation/EnableConfigurationProperties.java @@ -33,6 +33,6 @@ import org.springframework.context.annotation.Import; @Import(ConfigurationPropertiesImportSelector.class) public @interface EnableConfigurationProperties { - Class value() default void.class; + Class[] value() default { void.class }; } diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/properties/ManagementServerProperties.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/properties/ManagementServerProperties.java new file mode 100644 index 00000000000..c038abb88b3 --- /dev/null +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/properties/ManagementServerProperties.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.bootstrap.service.properties; + +import javax.validation.constraints.NotNull; + +import org.springframework.bootstrap.context.annotation.ConfigurationProperties; + +/** + * Properties for the management server (e.g. port and path settings). + * + * @author Dave Syer + */ +@ConfigurationProperties(name = "management", ignoreUnknownFields = false) +public class ManagementServerProperties { + + private int port = 8080; + + @NotNull + private String contextPath = ""; + + private boolean allowShutdown = false; + + public boolean isAllowShutdown() { + return this.allowShutdown; + } + + public void setAllowShutdown(boolean allowShutdown) { + this.allowShutdown = allowShutdown; + } + + public int getPort() { + return this.port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getContextPath() { + return this.contextPath; + } + + public void setContextPath(String contextPath) { + this.contextPath = contextPath; + } + +} diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/properties/ContainerProperties.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/properties/ServerProperties.java similarity index 70% rename from spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/properties/ContainerProperties.java rename to spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/properties/ServerProperties.java index b237caba36f..f7fb2434eb8 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/properties/ContainerProperties.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/properties/ServerProperties.java @@ -18,34 +18,31 @@ package org.springframework.bootstrap.service.properties; import java.io.File; +import javax.validation.constraints.NotNull; + import org.springframework.bootstrap.context.annotation.ConfigurationProperties; /** - * Properties for the web container (e.g. port and path settings). + * Properties for the web server (e.g. port and path settings). * * @author Dave Syer */ -@ConfigurationProperties(name = "container", ignoreUnknownFields = false) -public class ContainerProperties { +@ConfigurationProperties(name = "server", ignoreUnknownFields = false) +public class ServerProperties { private int port = 8080; - private int managementPort = this.port; - - private String contextPath; - - private boolean allowShutdown = false; + @NotNull + private String contextPath = ""; private Tomcat tomcat = new Tomcat(); - private boolean dumpRequests; - public Tomcat getTomcat() { return this.tomcat; } public String getContextPath() { - return this.contextPath == null ? "" : this.contextPath; + return this.contextPath; } public void setContextPath(String contextPath) { @@ -60,30 +57,6 @@ public class ContainerProperties { this.port = port; } - public int getManagementPort() { - return this.managementPort; - } - - public void setManagementPort(int managementPort) { - this.managementPort = managementPort; - } - - public boolean isAllowShutdown() { - return this.allowShutdown; - } - - public void setAllowShutdown(boolean allowShutdown) { - this.allowShutdown = allowShutdown; - } - - public boolean isDumpRequests() { - return this.dumpRequests; - } - - public void setDumpRequests(boolean dumpRequests) { - this.dumpRequests = dumpRequests; - } - public static class Tomcat { private String accessLogPattern; diff --git a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/shutdown/ShutdownEndpoint.java b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/shutdown/ShutdownEndpoint.java index 095062287ef..89ba8ee8121 100644 --- a/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/shutdown/ShutdownEndpoint.java +++ b/spring-bootstrap-service/src/main/java/org/springframework/bootstrap/service/shutdown/ShutdownEndpoint.java @@ -22,7 +22,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.bootstrap.service.properties.ContainerProperties; +import org.springframework.bootstrap.service.properties.ManagementServerProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationListener; @@ -46,7 +46,7 @@ public class ShutdownEndpoint implements ApplicationContextAware, private ConfigurableApplicationContext context; @Autowired - private ContainerProperties configuration = new ContainerProperties(); + private ManagementServerProperties configuration = new ManagementServerProperties(); private boolean shuttingDown = false;