diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java index 0b58722855..73cd87d95a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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,9 +23,7 @@ import java.util.HashSet; import java.util.List; import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.servlet.ServletContainer; -import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; import org.springframework.boot.actuate.endpoint.ExposableEndpoint; @@ -42,14 +40,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.jersey.JerseyProperties; import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; -import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; /** * {@link ManagementContextConfiguration} for Jersey {@link Endpoint} concerns. @@ -88,37 +80,4 @@ class JerseyWebEndpointManagementContextConfiguration { }; } - @Configuration - @ConditionalOnMissingBean(ResourceConfig.class) - @EnableConfigurationProperties(JerseyProperties.class) - static class ResourceConfigConfiguration { - - @Bean - public ResourceConfig resourceConfig( - ObjectProvider resourceConfigCustomizers) { - ResourceConfig resourceConfig = new ResourceConfig(); - resourceConfigCustomizers.orderedStream() - .forEach((customizer) -> customizer.customize(resourceConfig)); - return resourceConfig; - } - - @Bean - @ConditionalOnMissingBean - public JerseyApplicationPath jerseyApplicationPath(JerseyProperties properties, - ResourceConfig config) { - return new DefaultJerseyApplicationPath(properties.getApplicationPath(), - config); - } - - @Bean - public ServletRegistrationBean jerseyServletRegistration( - ObjectProvider resourceConfigCustomizers, - JerseyApplicationPath jerseyApplicationPath) { - return new ServletRegistrationBean<>( - new ServletContainer(resourceConfig(resourceConfigCustomizers)), - jerseyApplicationPath.getUrlMapping()); - } - - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementChildContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfiguration.java similarity index 53% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementChildContextConfiguration.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfiguration.java index 1497d8dee8..bfe0da9449 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementChildContextConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -13,57 +13,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.boot.actuate.autoconfigure.web.jersey; import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.servlet.ServletContainer; -import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; -import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; /** * {@link ManagementContextConfiguration} for Jersey infrastructure when a separate * management context with a web server running on a different port is required. * - * @author Stephane Nicoll - * @author Andy Wilkinson - * @author Phillip Webb - * @since 2.0.0 + * @author Madhura Bhave */ @ManagementContextConfiguration(ManagementContextType.CHILD) -@ConditionalOnWebApplication(type = Type.SERVLET) +@Import(JerseyManagementContextConfiguration.class) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @ConditionalOnClass(ResourceConfig.class) @ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet") -public class JerseyManagementChildContextConfiguration { - - private final ObjectProvider resourceConfigCustomizers; - - public JerseyManagementChildContextConfiguration( - ObjectProvider resourceConfigCustomizers) { - this.resourceConfigCustomizers = resourceConfigCustomizers; - } - - @Bean - public ServletRegistrationBean jerseyServletRegistration() { - return new ServletRegistrationBean<>( - new ServletContainer(endpointResourceConfig()), "/*"); - } +public class JerseyChildManagementContextConfiguration { @Bean - public ResourceConfig endpointResourceConfig() { - ResourceConfig resourceConfig = new ResourceConfig(); - this.resourceConfigCustomizers.orderedStream() - .forEach((customizer) -> customizer.customize(resourceConfig)); - return resourceConfig; + public JerseyApplicationPath jerseyApplicationPath() { + return () -> "/"; } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementContextConfiguration.java new file mode 100644 index 0000000000..28668ad208 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementContextConfiguration.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-2019 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.autoconfigure.web.jersey; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.servlet.ServletContainer; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; +import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; + +/** + * Shared configuration for Jersey-based actuators regardless of management context type. + * + * @author Madhura Bhave + */ +class JerseyManagementContextConfiguration { + + @Bean + public ServletRegistrationBean jerseyServletRegistration( + JerseyApplicationPath jerseyApplicationPath, ResourceConfig resourceConfig) { + return new ServletRegistrationBean<>(new ServletContainer(resourceConfig), + jerseyApplicationPath.getUrlMapping()); + } + + @Bean + public ResourceConfig resourceConfig( + ObjectProvider resourceConfigCustomizers) { + ResourceConfig resourceConfig = new ResourceConfig(); + resourceConfigCustomizers.orderedStream() + .forEach((customizer) -> customizer.customize(resourceConfig)); + return resourceConfig; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfiguration.java new file mode 100644 index 0000000000..8f83a7659d --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfiguration.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-2019 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.autoconfigure.web.jersey; + +import org.glassfish.jersey.server.ResourceConfig; + +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.jersey.JerseyProperties; +import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath; +import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; + +/** + * {@link ManagementContextConfiguration} for Jersey infrastructure when the management + * context is the same as the main application context. + * + * @author Madhura Bhave + */ +@ManagementContextConfiguration(ManagementContextType.SAME) +@ConditionalOnMissingBean(ResourceConfig.class) +@Import(JerseyManagementContextConfiguration.class) +@EnableConfigurationProperties(JerseyProperties.class) +@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) +@ConditionalOnClass(ResourceConfig.class) +@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet") +public class JerseySameManagementContextConfiguration { + + @Bean + @ConditionalOnMissingBean(JerseyApplicationPath.class) + public JerseyApplicationPath jerseyApplicationPath(JerseyProperties properties, + ResourceConfig config) { + return new DefaultJerseyApplicationPath(properties.getApplicationPath(), config); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories index 725355b6b9..cdfd9396c3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories @@ -94,7 +94,8 @@ org.springframework.boot.actuate.autoconfigure.endpoint.web.ServletEndpointManag org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey.JerseyWebEndpointManagementContextConfiguration,\ -org.springframework.boot.actuate.autoconfigure.web.jersey.JerseyManagementChildContextConfiguration,\ +org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration,\ +org.springframework.boot.actuate.autoconfigure.web.jersey.JerseyChildManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementChildContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementChildContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.servlet.WebMvcEndpointChildContextConfiguration diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfigurationTests.java index 0860a3cdaf..c656e3b685 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -19,23 +19,20 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey; import java.util.Collections; import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.servlet.ServletContainer; import org.junit.Test; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration; import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; -import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath; -import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; /** * Tests for {@link JerseyWebEndpointManagementContextConfiguration}. @@ -51,74 +48,25 @@ public class JerseyWebEndpointManagementContextConfigurationTests { .withUserConfiguration(WebEndpointsSupplierConfig.class); @Test - public void resourceConfigIsAutoConfiguredWhenNeeded() { - this.runner.run( - (context) -> assertThat(context).hasSingleBean(ResourceConfig.class)); - } - - @Test - public void jerseyApplicationPathIsAutoConfiguredWhenNeeded() { + public void resourceConfigCustomizerForEndpointsIsAutoConfigured() { this.runner.run((context) -> assertThat(context) - .hasSingleBean(DefaultJerseyApplicationPath.class)); - } - - @Test - public void jerseyApplicationPathIsConditionalOnMissinBean() { - this.runner.withUserConfiguration(ConfigWithJerseyApplicationPath.class) - .run((context) -> { - assertThat(context).hasSingleBean(JerseyApplicationPath.class); - assertThat(context).hasBean("testJerseyApplicationPath"); - }); - } - - @Test - @SuppressWarnings("unchecked") - public void servletRegistrationBeanIsAutoConfiguredWhenNeeded() { - this.runner.withPropertyValues("spring.jersey.application-path=/jersey") - .run((context) -> { - ServletRegistrationBean bean = context - .getBean(ServletRegistrationBean.class); - assertThat(bean.getUrlMappings()).containsExactly("/jersey/*"); - }); + .hasSingleBean(ResourceConfigCustomizer.class)); } @Test - public void existingResourceConfigBeanShouldNotAutoConfigureRelatedBeans() { - this.runner.withUserConfiguration(ConfigWithResourceConfig.class) - .run((context) -> { - assertThat(context).hasSingleBean(ResourceConfig.class); - assertThat(context).doesNotHaveBean(JerseyApplicationPath.class); - assertThat(context).doesNotHaveBean(ServletRegistrationBean.class); - assertThat(context).hasBean("customResourceConfig"); - }); + public void autoConfigurationIsConditionalOnServletWebApplication() { + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations + .of(JerseySameManagementContextConfiguration.class)); + contextRunner.run((context) -> assertThat(context) + .doesNotHaveBean(JerseySameManagementContextConfiguration.class)); } @Test - public void resourceConfigIsCustomizedWithResourceConfigCustomizerBean() { - this.runner.withUserConfiguration(CustomizerConfiguration.class) - .run((context) -> { - assertThat(context).hasSingleBean(ResourceConfig.class); - ResourceConfig config = context.getBean(ResourceConfig.class); - ResourceConfigCustomizer customizer = (ResourceConfigCustomizer) context - .getBean("testResourceConfigCustomizer"); - verify(customizer).customize(config); - }); - } - - @Test - public void resourceConfigCustomizerBeanIsNotRequired() { - this.runner.run( - (context) -> assertThat(context).hasSingleBean(ResourceConfig.class)); - } - - @Configuration - static class CustomizerConfiguration { - - @Bean - ResourceConfigCustomizer testResourceConfigCustomizer() { - return mock(ResourceConfigCustomizer.class); - } - + public void autoConfigurationIsConditionalOnClassResourceConfig() { + this.runner.withClassLoader(new FilteredClassLoader(ResourceConfig.class)) + .run((context) -> assertThat(context) + .doesNotHaveBean(JerseySameManagementContextConfiguration.class)); } @Configuration @@ -131,24 +79,4 @@ public class JerseyWebEndpointManagementContextConfigurationTests { } - @Configuration - static class ConfigWithResourceConfig { - - @Bean - public ResourceConfig customResourceConfig() { - return new ResourceConfig(); - } - - } - - @Configuration - static class ConfigWithJerseyApplicationPath { - - @Bean - public JerseyApplicationPath testJerseyApplicationPath() { - return mock(JerseyApplicationPath.class); - } - - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementChildContextConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfigurationTests.java similarity index 55% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementChildContextConfigurationTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfigurationTests.java index d81a1f0fd1..6063f535bf 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementChildContextConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,19 @@ package org.springframework.boot.actuate.autoconfigure.web.jersey; import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.servlet.ServletContainer; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; +import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions; import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; +import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -32,16 +38,33 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; /** - * Tests for {@link JerseyManagementChildContextConfiguration}. + * Tests for {@link JerseyChildManagementContextConfiguration}. * * @author Andy Wilkinson + * @author Madhura Bhave */ @RunWith(ModifiedClassPathRunner.class) @ClassPathExclusions("spring-webmvc-*") -public class JerseyManagementChildContextConfigurationTests { +public class JerseyChildManagementContextConfigurationTests { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withUserConfiguration(JerseyManagementChildContextConfiguration.class); + .withUserConfiguration(JerseyChildManagementContextConfiguration.class); + + @Test + public void autoConfigurationIsConditionalOnServletWebApplication() { + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations + .of(JerseySameManagementContextConfiguration.class)); + contextRunner.run((context) -> assertThat(context) + .doesNotHaveBean(JerseySameManagementContextConfiguration.class)); + } + + @Test + public void autoConfigurationIsConditionalOnClassResourceConfig() { + this.contextRunner.withClassLoader(new FilteredClassLoader(ResourceConfig.class)) + .run((context) -> assertThat(context) + .doesNotHaveBean(JerseySameManagementContextConfiguration.class)); + } @Test public void resourceConfigIsCustomizedWithResourceConfigCustomizerBean() { @@ -55,6 +78,24 @@ public class JerseyManagementChildContextConfigurationTests { }); } + @Test + public void jerseyApplicationPathIsAutoConfigured() { + this.contextRunner.run((context) -> { + JerseyApplicationPath bean = context.getBean(JerseyApplicationPath.class); + assertThat(bean.getPath()).isEqualTo("/"); + }); + } + + @Test + @SuppressWarnings("unchecked") + public void servletRegistrationBeanIsAutoConfigured() { + this.contextRunner.run((context) -> { + ServletRegistrationBean bean = context + .getBean(ServletRegistrationBean.class); + assertThat(bean.getUrlMappings()).containsExactly("/*"); + }); + } + @Test public void resourceConfigCustomizerBeanIsNotRequired() { this.contextRunner.run( diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfigurationTests.java new file mode 100644 index 0000000000..17e7e0d236 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfigurationTests.java @@ -0,0 +1,148 @@ +/* + * Copyright 2012-2019 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.autoconfigure.web.jersey; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.servlet.ServletContainer; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; +import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath; +import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions; +import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +/** + * Tests for {@link JerseySameManagementContextConfiguration}. + * + * @author Madhura Bhave + */ +@RunWith(ModifiedClassPathRunner.class) +@ClassPathExclusions("spring-webmvc-*") +public class JerseySameManagementContextConfigurationTests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations + .of(JerseySameManagementContextConfiguration.class)); + + @Test + public void autoConfigurationIsConditionalOnServletWebApplication() { + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations + .of(JerseySameManagementContextConfiguration.class)); + contextRunner.run((context) -> assertThat(context) + .doesNotHaveBean(JerseySameManagementContextConfiguration.class)); + } + + @Test + public void autoConfigurationIsConditionalOnClassResourceConfig() { + this.contextRunner.withClassLoader(new FilteredClassLoader(ResourceConfig.class)) + .run((context) -> assertThat(context) + .doesNotHaveBean(JerseySameManagementContextConfiguration.class)); + } + + @Test + public void resourceConfigIsCustomizedWithResourceConfigCustomizerBean() { + this.contextRunner.withUserConfiguration(CustomizerConfiguration.class) + .run((context) -> { + assertThat(context).hasSingleBean(ResourceConfig.class); + ResourceConfig config = context.getBean(ResourceConfig.class); + ResourceConfigCustomizer customizer = context + .getBean(ResourceConfigCustomizer.class); + verify(customizer).customize(config); + }); + } + + @Test + public void jerseyApplicationPathIsAutoConfiguredWhenNeeded() { + this.contextRunner.run((context) -> assertThat(context) + .hasSingleBean(DefaultJerseyApplicationPath.class)); + } + + @Test + public void jerseyApplicationPathIsConditionalOnMissingBean() { + this.contextRunner.withUserConfiguration(ConfigWithJerseyApplicationPath.class) + .run((context) -> { + assertThat(context).hasSingleBean(JerseyApplicationPath.class); + assertThat(context).hasBean("testJerseyApplicationPath"); + }); + } + + @Test + public void existingResourceConfigBeanShouldNotAutoConfigureRelatedBeans() { + this.contextRunner.withUserConfiguration(ConfigWithResourceConfig.class) + .run((context) -> { + assertThat(context).hasSingleBean(ResourceConfig.class); + assertThat(context).doesNotHaveBean(JerseyApplicationPath.class); + assertThat(context).doesNotHaveBean(ServletRegistrationBean.class); + assertThat(context).hasBean("customResourceConfig"); + }); + } + + @Test + @SuppressWarnings("unchecked") + public void servletRegistrationBeanIsAutoConfiguredWhenNeeded() { + this.contextRunner.withPropertyValues("spring.jersey.application-path=/jersey") + .run((context) -> { + ServletRegistrationBean bean = context + .getBean(ServletRegistrationBean.class); + assertThat(bean.getUrlMappings()).containsExactly("/jersey/*"); + }); + } + + @Configuration + static class ConfigWithJerseyApplicationPath { + + @Bean + public JerseyApplicationPath testJerseyApplicationPath() { + return mock(JerseyApplicationPath.class); + } + + } + + @Configuration + static class ConfigWithResourceConfig { + + @Bean + public ResourceConfig customResourceConfig() { + return new ResourceConfig(); + } + + } + + @Configuration + static class CustomizerConfiguration { + + @Bean + ResourceConfigCustomizer resourceConfigCustomizer() { + return mock(ResourceConfigCustomizer.class); + } + + } + +} diff --git a/spring-boot-samples/spring-boot-sample-jersey/src/test/java/sample/jersey/JerseyApplicationPathAndManagementPortTests.java b/spring-boot-samples/spring-boot-sample-jersey/src/test/java/sample/jersey/JerseyApplicationPathAndManagementPortTests.java new file mode 100644 index 0000000000..08a2bc3692 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jersey/src/test/java/sample/jersey/JerseyApplicationPathAndManagementPortTests.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-2019 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 sample.jersey; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for separate management and main service ports with custom + * application path. + * + * @author Madhura Bhave + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { + "management.server.port=0", "spring.jersey.application-path=/app" }) +public class JerseyApplicationPathAndManagementPortTests { + + @LocalServerPort + private int port = 9010; + + @LocalManagementPort + private int managementPort = 9011; + + @Autowired + private TestRestTemplate testRestTemplate; + + @Test + public void applicationPathShouldNotAffectActuators() { + ResponseEntity entity = this.testRestTemplate.getForEntity( + "http://localhost:" + this.managementPort + "/actuator/health", + String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).contains("\"status\":\"UP\""); + } + +} +