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
This commit is contained in:
@@ -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;
|
||||
|
||||
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;
|
||||
@@ -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;
|
||||
|
||||
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;
|
||||
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 {
|
||||
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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user