Split Jersey management context configuration

This commit splits the management context configuration for jersey
into two separate configurations depending on if the type is SAME or
CHILD. The configuration for the SAME context should only kick in if
there is no existing ResourceConfig bean.

Fixes gh-15891
pull/15951/head
Madhura Bhave 6 years ago
parent b645e0a581
commit bbe555a4f5

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 java.util.List;
import org.glassfish.jersey.server.ResourceConfig; 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.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint; 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.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; 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.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.Bean;
import org.springframework.context.annotation.Configuration;
/** /**
* {@link ManagementContextConfiguration} for Jersey {@link Endpoint} concerns. * {@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<ResourceConfigCustomizer> 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<ServletContainer> jerseyServletRegistration(
ObjectProvider<ResourceConfigCustomizer> resourceConfigCustomizers,
JerseyApplicationPath jerseyApplicationPath) {
return new ServletRegistrationBean<>(
new ServletContainer(resourceConfig(resourceConfigCustomizers)),
jerseyApplicationPath.getUrlMapping());
}
}
} }

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.actuate.autoconfigure.web.jersey; package org.springframework.boot.actuate.autoconfigure.web.jersey;
import org.glassfish.jersey.server.ResourceConfig; 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.ManagementContextConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextType;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath;
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
/** /**
* {@link ManagementContextConfiguration} for Jersey infrastructure when a separate * {@link ManagementContextConfiguration} for Jersey infrastructure when a separate
* management context with a web server running on a different port is required. * management context with a web server running on a different port is required.
* *
* @author Stephane Nicoll * @author Madhura Bhave
* @author Andy Wilkinson
* @author Phillip Webb
* @since 2.0.0
*/ */
@ManagementContextConfiguration(ManagementContextType.CHILD) @ManagementContextConfiguration(ManagementContextType.CHILD)
@ConditionalOnWebApplication(type = Type.SERVLET) @Import(JerseyManagementContextConfiguration.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(ResourceConfig.class) @ConditionalOnClass(ResourceConfig.class)
@ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet") @ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet")
public class JerseyManagementChildContextConfiguration { public class JerseyChildManagementContextConfiguration {
private final ObjectProvider<ResourceConfigCustomizer> resourceConfigCustomizers;
public JerseyManagementChildContextConfiguration(
ObjectProvider<ResourceConfigCustomizer> resourceConfigCustomizers) {
this.resourceConfigCustomizers = resourceConfigCustomizers;
}
@Bean
public ServletRegistrationBean<ServletContainer> jerseyServletRegistration() {
return new ServletRegistrationBean<>(
new ServletContainer(endpointResourceConfig()), "/*");
}
@Bean @Bean
public ResourceConfig endpointResourceConfig() { public JerseyApplicationPath jerseyApplicationPath() {
ResourceConfig resourceConfig = new ResourceConfig(); return () -> "/";
this.resourceConfigCustomizers.orderedStream()
.forEach((customizer) -> customizer.customize(resourceConfig));
return resourceConfig;
} }
} }

@ -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<ServletContainer> jerseyServletRegistration(
JerseyApplicationPath jerseyApplicationPath, ResourceConfig resourceConfig) {
return new ServletRegistrationBean<>(new ServletContainer(resourceConfig),
jerseyApplicationPath.getUrlMapping());
}
@Bean
public ResourceConfig resourceConfig(
ObjectProvider<ResourceConfigCustomizer> resourceConfigCustomizers) {
ResourceConfig resourceConfig = new ResourceConfig();
resourceConfigCustomizers.orderedStream()
.forEach((customizer) -> customizer.customize(resourceConfig));
return resourceConfig;
}
}

@ -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);
}
}

@ -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.reactive.WebFluxEndpointManagementContextConfiguration,\
org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration,\
org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey.JerseyWebEndpointManagementContextConfiguration,\ 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.reactive.ReactiveManagementChildContextConfiguration,\
org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementChildContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementChildContextConfiguration,\
org.springframework.boot.actuate.autoconfigure.web.servlet.WebMvcEndpointChildContextConfiguration org.springframework.boot.actuate.autoconfigure.web.servlet.WebMvcEndpointChildContextConfiguration

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 java.util.Collections;
import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; 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.actuate.endpoint.web.WebEndpointsSupplier;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
import org.springframework.boot.autoconfigure.web.servlet.DefaultJerseyApplicationPath; import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.autoconfigure.web.servlet.JerseyApplicationPath; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner; 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.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/** /**
* Tests for {@link JerseyWebEndpointManagementContextConfiguration}. * Tests for {@link JerseyWebEndpointManagementContextConfiguration}.
@ -51,74 +48,25 @@ public class JerseyWebEndpointManagementContextConfigurationTests {
.withUserConfiguration(WebEndpointsSupplierConfig.class); .withUserConfiguration(WebEndpointsSupplierConfig.class);
@Test @Test
public void resourceConfigIsAutoConfiguredWhenNeeded() { public void resourceConfigCustomizerForEndpointsIsAutoConfigured() {
this.runner.run(
(context) -> assertThat(context).hasSingleBean(ResourceConfig.class));
}
@Test
public void jerseyApplicationPathIsAutoConfiguredWhenNeeded() {
this.runner.run((context) -> assertThat(context) this.runner.run((context) -> assertThat(context)
.hasSingleBean(DefaultJerseyApplicationPath.class)); .hasSingleBean(ResourceConfigCustomizer.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<ServletContainer> bean = context
.getBean(ServletRegistrationBean.class);
assertThat(bean.getUrlMappings()).containsExactly("/jersey/*");
});
} }
@Test @Test
public void existingResourceConfigBeanShouldNotAutoConfigureRelatedBeans() { public void autoConfigurationIsConditionalOnServletWebApplication() {
this.runner.withUserConfiguration(ConfigWithResourceConfig.class) ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.run((context) -> { .withConfiguration(AutoConfigurations
assertThat(context).hasSingleBean(ResourceConfig.class); .of(JerseySameManagementContextConfiguration.class));
assertThat(context).doesNotHaveBean(JerseyApplicationPath.class); contextRunner.run((context) -> assertThat(context)
assertThat(context).doesNotHaveBean(ServletRegistrationBean.class); .doesNotHaveBean(JerseySameManagementContextConfiguration.class));
assertThat(context).hasBean("customResourceConfig");
});
} }
@Test @Test
public void resourceConfigIsCustomizedWithResourceConfigCustomizerBean() { public void autoConfigurationIsConditionalOnClassResourceConfig() {
this.runner.withUserConfiguration(CustomizerConfiguration.class) this.runner.withClassLoader(new FilteredClassLoader(ResourceConfig.class))
.run((context) -> { .run((context) -> assertThat(context)
assertThat(context).hasSingleBean(ResourceConfig.class); .doesNotHaveBean(JerseySameManagementContextConfiguration.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);
}
} }
@Configuration @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);
}
}
} }

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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; package org.springframework.boot.actuate.autoconfigure.web.jersey;
import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer; 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.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions; import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; 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.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -32,16 +38,33 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
/** /**
* Tests for {@link JerseyManagementChildContextConfiguration}. * Tests for {@link JerseyChildManagementContextConfiguration}.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Madhura Bhave
*/ */
@RunWith(ModifiedClassPathRunner.class) @RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions("spring-webmvc-*") @ClassPathExclusions("spring-webmvc-*")
public class JerseyManagementChildContextConfigurationTests { public class JerseyChildManagementContextConfigurationTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() 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 @Test
public void resourceConfigIsCustomizedWithResourceConfigCustomizerBean() { 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<ServletContainer> bean = context
.getBean(ServletRegistrationBean.class);
assertThat(bean.getUrlMappings()).containsExactly("/*");
});
}
@Test @Test
public void resourceConfigCustomizerBeanIsNotRequired() { public void resourceConfigCustomizerBeanIsNotRequired() {
this.contextRunner.run( this.contextRunner.run(

@ -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<ServletContainer> 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);
}
}
}

@ -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<String> entity = this.testRestTemplate.getForEntity(
"http://localhost:" + this.managementPort + "/actuator/health",
String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
}
}
Loading…
Cancel
Save