Browse Source

Use ResourceConfig customization to register endpoints with Jersey

Previously, actuator endpoints were registered with Jersey upon
injection of the ResourceConfig bean into a registrar class rather than
using a ResourceConfigCustomizer. This was done to fix a problem
when running the Actuator on a separate port where the main application
context's customizers were also applied to the management context,
breaking the singleton contract for those resources. This approach
meant that the registration could be performed at any point after the
ResourceConfig had been created. When Jersey's configured as a Filter
this resulted in the registration failing as the attempt was being made
after the Filter lifecyle callbacks which make the ResourceConfig
immutable.

This commit reworks the endpoint registration to be performed using a
ManagementContextResourceConfigCustomizer, a resource config customizer
that's only applied to the ResourceConfig that's used by the Actuator.
When there's a separate management context, this ResourceConfig is
created by the Actuator's auto-configuration and the management context
resource config customizers are applied to it during its creation. The
main application's customizers are not applied. When the actuator is
using the same context as the main application, this ResourceConfig is
created by the main application. In this case a
ResourceConfigCustomizer is defined that delegates to all
ManagementContextResourceConfigCustomizers, allowing them to register
the actuator endpoints with the main ResourceConfig.

Fixes gh-25262
pull/25486/head
Andy Wilkinson 5 years ago
parent
commit
8f72ca6521
  1. 49
      spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java
  2. 10
      spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfiguration.java
  3. 7
      spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementContextConfiguration.java
  4. 33
      spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfiguration.java
  5. 36
      spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/ManagementContextResourceConfigCustomizer.java
  6. 78
      spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java
  7. 27
      spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfigurationTests.java
  8. 24
      spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfigurationTests.java
  9. 6
      spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyApplicationTests.java
  10. 27
      spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyManagementPortTests.java
  11. 29
      spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyFilterApplicationTests.java
  12. 30
      spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyFilterManagementPortTests.java
  13. 26
      spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyServletApplicationTests.java
  14. 27
      spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyServletManagementPortTests.java

49
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointManagementContextConfiguration.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
@ -24,9 +24,9 @@ import java.util.List; @@ -24,9 +24,9 @@ import java.util.List;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.model.Resource;
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.autoconfigure.web.jersey.ManagementContextResourceConfigCustomizer;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
@ -43,7 +43,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -43,7 +43,6 @@ 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.ResourceConfigCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
@ -67,14 +66,13 @@ class JerseyWebEndpointManagementContextConfiguration { @@ -67,14 +66,13 @@ class JerseyWebEndpointManagementContextConfiguration {
@Bean
JerseyWebEndpointsResourcesRegistrar jerseyWebEndpointsResourcesRegistrar(Environment environment,
ObjectProvider<ResourceConfig> resourceConfig, WebEndpointsSupplier webEndpointsSupplier,
ServletEndpointsSupplier servletEndpointsSupplier, EndpointMediaTypes endpointMediaTypes,
WebEndpointProperties webEndpointProperties) {
WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier,
EndpointMediaTypes endpointMediaTypes, WebEndpointProperties webEndpointProperties) {
String basePath = webEndpointProperties.getBasePath();
boolean shouldRegisterLinks = shouldRegisterLinksMapping(environment, basePath);
shouldRegisterLinksMapping(environment, basePath);
return new JerseyWebEndpointsResourcesRegistrar(resourceConfig.getIfAvailable(), webEndpointsSupplier,
servletEndpointsSupplier, endpointMediaTypes, basePath, shouldRegisterLinks);
return new JerseyWebEndpointsResourcesRegistrar(webEndpointsSupplier, servletEndpointsSupplier,
endpointMediaTypes, basePath, shouldRegisterLinks);
}
private boolean shouldRegisterLinksMapping(Environment environment, String basePath) {
@ -83,12 +81,9 @@ class JerseyWebEndpointManagementContextConfiguration { @@ -83,12 +81,9 @@ class JerseyWebEndpointManagementContextConfiguration {
}
/**
* Register endpoints with the {@link ResourceConfig}. The
* {@link ResourceConfigCustomizer} cannot be used because we don't want to apply
* Register endpoints with the {@link ResourceConfig} for the management context.
*/
static class JerseyWebEndpointsResourcesRegistrar {
private final ResourceConfig resourceConfig;
static class JerseyWebEndpointsResourcesRegistrar implements ManagementContextResourceConfigCustomizer {
private final WebEndpointsSupplier webEndpointsSupplier;
@ -100,33 +95,29 @@ class JerseyWebEndpointManagementContextConfiguration { @@ -100,33 +95,29 @@ class JerseyWebEndpointManagementContextConfiguration {
private final boolean shouldRegisterLinks;
JerseyWebEndpointsResourcesRegistrar(ResourceConfig resourceConfig, WebEndpointsSupplier webEndpointsSupplier,
JerseyWebEndpointsResourcesRegistrar(WebEndpointsSupplier webEndpointsSupplier,
ServletEndpointsSupplier servletEndpointsSupplier, EndpointMediaTypes endpointMediaTypes,
String basePath, boolean shouldRegisterLinks) {
super();
this.resourceConfig = resourceConfig;
this.webEndpointsSupplier = webEndpointsSupplier;
this.servletEndpointsSupplier = servletEndpointsSupplier;
this.mediaTypes = endpointMediaTypes;
this.basePath = basePath;
this.shouldRegisterLinks = shouldRegisterLinks;
register();
}
private void register() {
// We can't easily use @ConditionalOnBean because @AutoConfigureBefore is
// not an option for management contexts. Instead we manually check if
// the resource config bean exists
if (this.resourceConfig == null) {
return;
}
@Override
public void customize(ResourceConfig config) {
register(config);
}
private void register(ResourceConfig config) {
Collection<ExposableWebEndpoint> webEndpoints = this.webEndpointsSupplier.getEndpoints();
Collection<ExposableServletEndpoint> servletEndpoints = this.servletEndpointsSupplier.getEndpoints();
EndpointLinksResolver linksResolver = getLinksResolver(webEndpoints, servletEndpoints);
EndpointMapping mapping = new EndpointMapping(this.basePath);
JerseyEndpointResourceFactory resourceFactory = new JerseyEndpointResourceFactory();
register(resourceFactory.createEndpointResources(mapping, webEndpoints, this.mediaTypes, linksResolver,
this.shouldRegisterLinks));
Collection<Resource> endpointResources = new JerseyEndpointResourceFactory().createEndpointResources(
mapping, webEndpoints, this.mediaTypes, linksResolver, this.shouldRegisterLinks);
register(endpointResources, config);
}
private EndpointLinksResolver getLinksResolver(Collection<ExposableWebEndpoint> webEndpoints,
@ -137,8 +128,8 @@ class JerseyWebEndpointManagementContextConfiguration { @@ -137,8 +128,8 @@ class JerseyWebEndpointManagementContextConfiguration {
return new EndpointLinksResolver(endpoints, this.basePath);
}
private void register(Collection<Resource> resources) {
this.resourceConfig.registerResources(new HashSet<>(resources));
private void register(Collection<Resource> resources, ResourceConfig config) {
config.registerResources(new HashSet<>(resources));
}
}

10
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfiguration.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
@ -18,6 +18,7 @@ package org.springframework.boot.actuate.autoconfigure.web.jersey; @@ -18,6 +18,7 @@ package org.springframework.boot.actuate.autoconfigure.web.jersey;
import org.glassfish.jersey.server.ResourceConfig;
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;
@ -47,4 +48,11 @@ public class JerseyChildManagementContextConfiguration { @@ -47,4 +48,11 @@ public class JerseyChildManagementContextConfiguration {
return () -> "/";
}
@Bean
ResourceConfig resourceConfig(ObjectProvider<ManagementContextResourceConfigCustomizer> customizers) {
ResourceConfig resourceConfig = new ResourceConfig();
customizers.orderedStream().forEach((customizer) -> customizer.customize(resourceConfig));
return resourceConfig;
}
}

7
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyManagementContextConfiguration.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 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.
@ -39,9 +39,4 @@ class JerseyManagementContextConfiguration { @@ -39,9 +39,4 @@ class JerseyManagementContextConfiguration {
jerseyApplicationPath.getUrlMapping());
}
@Bean
ResourceConfig resourceConfig() {
return new ResourceConfig();
}
}

33
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfiguration.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
@ -18,6 +18,7 @@ package org.springframework.boot.actuate.autoconfigure.web.jersey; @@ -18,6 +18,7 @@ package org.springframework.boot.actuate.autoconfigure.web.jersey;
import org.glassfish.jersey.server.ResourceConfig;
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;
@ -25,10 +26,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean @@ -25,10 +26,12 @@ 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.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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
@ -39,18 +42,36 @@ import org.springframework.context.annotation.Import; @@ -39,18 +42,36 @@ import org.springframework.context.annotation.Import;
* @since 2.1.0
*/
@ManagementContextConfiguration(value = ManagementContextType.SAME, proxyBeanMethods = false)
@Import(JerseyManagementContextConfiguration.class)
@EnableConfigurationProperties(JerseyProperties.class)
@ConditionalOnMissingBean(ResourceConfig.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);
ResourceConfigCustomizer managementResourceConfigCustomizerAdapter(
ObjectProvider<ManagementContextResourceConfigCustomizer> customizers) {
return (config) -> customizers.orderedStream().forEach((customizer) -> customizer.customize(config));
}
@Configuration(proxyBeanMethods = false)
@Import(JerseyManagementContextConfiguration.class)
@ConditionalOnMissingBean(ResourceConfig.class)
class JerseyInfrastructureConfiguration {
@Bean
@ConditionalOnMissingBean(JerseyApplicationPath.class)
JerseyApplicationPath jerseyApplicationPath(JerseyProperties properties, ResourceConfig config) {
return new DefaultJerseyApplicationPath(properties.getApplicationPath(), config);
}
@Bean
ResourceConfig resourceConfig(ObjectProvider<ResourceConfigCustomizer> resourceConfigCustomizers) {
ResourceConfig resourceConfig = new ResourceConfig();
resourceConfigCustomizers.orderedStream().forEach((customizer) -> customizer.customize(resourceConfig));
return resourceConfig;
}
}
}

36
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/jersey/ManagementContextResourceConfigCustomizer.java

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
/*
* Copyright 2012-2021 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
*
* https://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;
/**
* Callback interface that can be implemented by beans wishing to customize Jersey's
* {@link ResourceConfig} in the management context before it is used.
*
* @author Andy Wilkinson
* @since 2.3.10
*/
public interface ManagementContextResourceConfigCustomizer {
/**
* Customize the resource config.
* @param config the {@link ResourceConfig} to customize
*/
void customize(ResourceConfig config);
}

78
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
/*
* Copyright 2012-2021 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
*
* https://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.endpoint.web.jersey;
import java.util.Set;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.model.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.jersey.JerseySameManagementContextConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener;
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.DispatcherServlet;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for web endpoints running on Jersey.
*
* @author Andy Wilkinson
*/
class JerseyWebEndpointIntegrationTests {
@Test
void whenJerseyIsConfiguredToUseAFilterThenResourceRegistrationSucceeds() {
new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
.withConfiguration(AutoConfigurations.of(JerseySameManagementContextConfiguration.class,
JerseyAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class,
EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
JerseyWebEndpointManagementContextConfiguration.class))
.withUserConfiguration(ResourceConfigConfiguration.class)
.withClassLoader(new FilteredClassLoader(DispatcherServlet.class))
.withInitializer(new ConditionEvaluationReportLoggingListener(LogLevel.INFO))
.withPropertyValues("spring.jersey.type=filter", "server.port=0").run((context) -> {
assertThat(context).hasNotFailed();
Set<Resource> resources = context.getBean(ResourceConfig.class).getResources();
assertThat(resources).hasSize(1);
Resource resource = resources.iterator().next();
assertThat(resource.getPath()).isEqualTo("/actuator");
});
}
@Configuration(proxyBeanMethods = false)
static class ResourceConfigConfiguration {
@Bean
ResourceConfig resourceConfig() {
return new ResourceConfig();
}
}
}

27
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseyChildManagementContextConfigurationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 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.
@ -27,8 +27,12 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -27,8 +27,12 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
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 JerseyChildManagementContextConfiguration}.
@ -78,4 +82,25 @@ class JerseyChildManagementContextConfigurationTests { @@ -78,4 +82,25 @@ class JerseyChildManagementContextConfigurationTests {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ResourceConfig.class));
}
@Test
void resourceConfigIsCustomizedWithResourceConfigCustomizerBean() {
this.contextRunner.withUserConfiguration(CustomizerConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(ResourceConfig.class);
ResourceConfig config = context.getBean(ResourceConfig.class);
ManagementContextResourceConfigCustomizer customizer = context
.getBean(ManagementContextResourceConfigCustomizer.class);
verify(customizer).customize(config);
});
}
@Configuration(proxyBeanMethods = false)
static class CustomizerConfiguration {
@Bean
ManagementContextResourceConfigCustomizer resourceConfigCustomizer() {
return mock(ManagementContextResourceConfigCustomizer.class);
}
}
}

24
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/jersey/JerseySameManagementContextConfigurationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 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.
@ -33,6 +33,7 @@ import org.springframework.context.annotation.Configuration; @@ -33,6 +33,7 @@ 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}.
@ -91,6 +92,17 @@ class JerseySameManagementContextConfigurationTests { @@ -91,6 +92,17 @@ class JerseySameManagementContextConfigurationTests {
});
}
@Test
void resourceConfigIsCustomizedWithResourceConfigCustomizerBean() {
this.contextRunner.withUserConfiguration(CustomizerConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(ResourceConfig.class);
ResourceConfig config = context.getBean(ResourceConfig.class);
ManagementContextResourceConfigCustomizer customizer = context
.getBean(ManagementContextResourceConfigCustomizer.class);
verify(customizer).customize(config);
});
}
@Configuration(proxyBeanMethods = false)
static class ConfigWithJerseyApplicationPath {
@ -111,4 +123,14 @@ class JerseySameManagementContextConfigurationTests { @@ -111,4 +123,14 @@ class JerseySameManagementContextConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class CustomizerConfiguration {
@Bean
ManagementContextResourceConfigCustomizer resourceConfigCustomizer() {
return mock(ManagementContextResourceConfigCustomizer.class);
}
}
}

6
spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/SampleJerseyApplicationTests.java → spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyApplicationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 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.
@ -27,8 +27,8 @@ import org.springframework.http.ResponseEntity; @@ -27,8 +27,8 @@ import org.springframework.http.ResponseEntity;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class SampleJerseyApplicationTests {
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "logging.level.root=debug")
abstract class AbstractJerseyApplicationTests {
@Autowired
private TestRestTemplate restTemplate;

27
spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyManagementPortTests.java → spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyManagementPortTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 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.
@ -21,6 +21,7 @@ import javax.ws.rs.Path; @@ -21,6 +21,7 @@ import javax.ws.rs.Path;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.jupiter.api.Test;
import smoketest.jersey.AbstractJerseyManagementPortTests.ResourceConfigConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.web.server.LocalManagementPort;
@ -30,18 +31,22 @@ import org.springframework.boot.test.context.TestConfiguration; @@ -30,18 +31,22 @@ import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for separate management and main service ports.
* Base class for integration tests for Jersey using separate management and main service
* ports.
*
* @author Madhura Bhave
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = "management.server.port=0")
class JerseyManagementPortTests {
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "management.server.port=0", "debug=true" })
@Import(ResourceConfigConfiguration.class)
class AbstractJerseyManagementPortTests {
@LocalServerPort
private int port;
@ -67,6 +72,20 @@ class JerseyManagementPortTests { @@ -67,6 +72,20 @@ class JerseyManagementPortTests {
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
}
@Test
void actuatorShouldBeAvailableOnManagementPort() {
ResponseEntity<String> entity = this.testRestTemplate
.getForEntity("http://localhost:" + this.managementPort + "/actuator/health", String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@Test
void actuatorShouldNotBeAvailableOnMainPort() {
ResponseEntity<String> entity = this.testRestTemplate
.getForEntity("http://localhost:" + this.port + "/actuator/health", String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
}
@TestConfiguration
static class ResourceConfigConfiguration {

29
spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyFilterApplicationTests.java

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
/*
* Copyright 2012-2021 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
*
* https://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 smoketest.jersey;
import org.springframework.test.context.TestPropertySource;
/**
* Smoke tests for Jersey configured as a Filter.
*
* @author Andy Wilkinson
*/
@TestPropertySource(properties = "spring.jersey.type=filter")
class JerseyFilterApplicationTests extends AbstractJerseyApplicationTests {
}

30
spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyFilterManagementPortTests.java

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
/*
* Copyright 2012-2021 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
*
* https://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 smoketest.jersey;
import org.springframework.test.context.TestPropertySource;
/**
* Integration tests for Jersey configured as a Servlet using separate management and main
* service ports.
*
* @author Andy Wilkinson
*/
@TestPropertySource(properties = "spring.jersey.type=filter")
public class JerseyFilterManagementPortTests extends AbstractJerseyManagementPortTests {
}

26
spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyServletApplicationTests.java

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
/*
* Copyright 2012-2021 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
*
* https://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 smoketest.jersey;
/**
* Smoke tests for Jersey configured as a Servlet.
*
* @author Andy Wilkinson
*/
class JerseyServletApplicationTests extends AbstractJerseyApplicationTests {
}

27
spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyServletManagementPortTests.java

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
/*
* Copyright 2012-2021 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
*
* https://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 smoketest.jersey;
/**
* Integration tests for Jersey configured as a Servlet using separate management and main
* service ports.
*
* @author Andy Wilkinson
*/
public class JerseyServletManagementPortTests extends AbstractJerseyManagementPortTests {
}
Loading…
Cancel
Save