From 82254e3b4d715a3185dd3619bfef44e438d9d61e Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 8 Nov 2022 21:40:51 -0800 Subject: [PATCH] Update smoketests to test isolated actuator object mapper use See gh-32297 See gh-20291 --- .../actuator/SampleActuatorApplication.java | 13 ++-- .../src/main/resources/application.properties | 2 + ...icationStartupSpringBootContextLoader.java | 32 ++++++++++ ...icationIsolatedObjectMapperFalseTests.java | 52 ++++++++++++++++ ...licationIsolatedObjectMapperTrueTests.java | 53 ++++++++++++++++ .../jersey/SampleJerseyApplication.java | 4 +- .../src/main/resources/application.properties | 3 + ...icationStartupSpringBootContextLoader.java | 32 ++++++++++ ...ctuatorIsolatedObjectMapperFalseTests.java | 62 +++++++++++++++++++ ...ActuatorIsolatedObjectMapperTrueTests.java | 61 ++++++++++++++++++ .../webflux/SampleWebFluxApplication.java | 7 ++- .../src/main/resources/application.properties | 3 + ...icationStartupSpringBootContextLoader.java | 32 ++++++++++ ...pplicationActuatorDifferentPortTests.java} | 2 +- ...ctuatorIsolatedObjectMapperFalseTests.java | 47 ++++++++++++++ ...ActuatorIsolatedObjectMapperTrueTests.java | 57 +++++++++++++++++ 16 files changed, 453 insertions(+), 9 deletions(-) create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ApplicationStartupSpringBootContextLoader.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperFalseTests.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperTrueTests.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/main/resources/application.properties create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/ApplicationStartupSpringBootContextLoader.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperFalseTests.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperTrueTests.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/main/resources/application.properties create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/ApplicationStartupSpringBootContextLoader.java rename spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/{WebFluxDifferentPortSampleActuatorApplicationTests.java => SampleWebFluxApplicationActuatorDifferentPortTests.java} (96%) create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorIsolatedObjectMapperFalseTests.java create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorIsolatedObjectMapperTrueTests.java diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/SampleActuatorApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/SampleActuatorApplication.java index d98a9092b9..f7264d52bf 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/SampleActuatorApplication.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/java/smoketest/actuator/SampleActuatorApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 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. @@ -25,6 +25,7 @@ import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthContributor; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; import org.springframework.context.annotation.Bean; @@ -32,10 +33,6 @@ import org.springframework.context.annotation.Bean; @ConfigurationPropertiesScan public class SampleActuatorApplication { - public static void main(String[] args) { - SpringApplication.run(SampleActuatorApplication.class, args); - } - @Bean public HealthIndicator helloHealthIndicator() { return createHealthIndicator("world"); @@ -61,4 +58,10 @@ public class SampleActuatorApplication { return () -> Health.up().withDetail("hello", value).build(); } + public static void main(String[] args) { + SpringApplication application = new SpringApplication(SampleActuatorApplication.class); + application.setApplicationStartup(new BufferingApplicationStartup(1024)); + application.run(args); + } + } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/resources/application.properties b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/resources/application.properties index 2a05e8284e..81cc777bfc 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/resources/application.properties +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/main/resources/application.properties @@ -28,3 +28,5 @@ management.endpoint.health.group.comp.show-details=always management.endpoints.migrate-legacy-ids=true +management.endpoints.jackson.isolated-object-mapper=true +spring.jackson.visibility.field=any diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ApplicationStartupSpringBootContextLoader.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ApplicationStartupSpringBootContextLoader.java new file mode 100644 index 0000000000..584274fddb --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ApplicationStartupSpringBootContextLoader.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-2022 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.actuator; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; +import org.springframework.boot.test.context.SpringBootContextLoader; + +class ApplicationStartupSpringBootContextLoader extends SpringBootContextLoader { + + @Override + protected SpringApplication getSpringApplication() { + SpringApplication application = new SpringApplication(); + application.setApplicationStartup(new BufferingApplicationStartup(1024)); + return application; + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperFalseTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperFalseTests.java new file mode 100644 index 0000000000..4a77556a88 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperFalseTests.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2022 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.actuator; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ContextConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration test for WebMVC actuator when using an isolated {@link ObjectMapper}. + * + * @author Phillip Webb + */ +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, + properties = "management.endpoints.jackson.isolated-object-mapper=false") +@ContextConfiguration(loader = ApplicationStartupSpringBootContextLoader.class) +class SampleActuatorApplicationIsolatedObjectMapperFalseTests { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Test + void resourceShouldBeAvailableOnMainPort() { + ResponseEntity entity = this.testRestTemplate.withBasicAuth("user", "password") + .getForEntity("/actuator/startup", String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperTrueTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperTrueTests.java new file mode 100644 index 0000000000..120da39375 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/SampleActuatorApplicationIsolatedObjectMapperTrueTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-2022 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.actuator; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ContextConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration test for WebMVC actuator when using an isolated {@link ObjectMapper}. + * + * @author Phillip Webb + */ +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, + properties = "management.endpoints.jackson.isolated-object-mapper=true") +@ContextConfiguration(loader = ApplicationStartupSpringBootContextLoader.class) +class SampleActuatorApplicationIsolatedObjectMapperTrueTests { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Test + void resourceShouldBeAvailableOnMainPort() { + ResponseEntity entity = this.testRestTemplate.withBasicAuth("user", "password") + .getForEntity("/actuator/startup", String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).contains("\"timeline\":"); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/main/java/smoketest/jersey/SampleJerseyApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/main/java/smoketest/jersey/SampleJerseyApplication.java index 0027e21df5..d44e50c5d4 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/main/java/smoketest/jersey/SampleJerseyApplication.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/main/java/smoketest/jersey/SampleJerseyApplication.java @@ -18,13 +18,15 @@ package smoketest.jersey; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication public class SampleJerseyApplication extends SpringBootServletInitializer { public static void main(String[] args) { - new SampleJerseyApplication().configure(new SpringApplicationBuilder(SampleJerseyApplication.class)).run(args); + new SampleJerseyApplication().configure(new SpringApplicationBuilder(SampleJerseyApplication.class) + .applicationStartup(new BufferingApplicationStartup(2048))).run(args); } } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/main/resources/application.properties b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/main/resources/application.properties new file mode 100644 index 0000000000..641c39e657 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/main/resources/application.properties @@ -0,0 +1,3 @@ +management.endpoints.web.exposure.include=* +management.endpoints.jackson.isolated-object-mapper=true +spring.jackson.visibility.field=any diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/ApplicationStartupSpringBootContextLoader.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/ApplicationStartupSpringBootContextLoader.java new file mode 100644 index 0000000000..4d16b9e19d --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/ApplicationStartupSpringBootContextLoader.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-2022 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.boot.SpringApplication; +import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; +import org.springframework.boot.test.context.SpringBootContextLoader; + +class ApplicationStartupSpringBootContextLoader extends SpringBootContextLoader { + + @Override + protected SpringApplication getSpringApplication() { + SpringApplication application = new SpringApplication(); + application.setApplicationStartup(new BufferingApplicationStartup(1024)); + return application; + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperFalseTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperFalseTests.java new file mode 100644 index 0000000000..e359fd94d2 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperFalseTests.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-2022 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 com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ContextConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration test for Jersey actuator when not using an isolated {@link ObjectMapper}. + * + * @author Phillip Webb + */ +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, + properties = "management.endpoints.jackson.isolated-object-mapper=false") +@ContextConfiguration(loader = ApplicationStartupSpringBootContextLoader.class) +public class JerseyActuatorIsolatedObjectMapperFalseTests { + + @LocalServerPort + private int port; + + @LocalManagementPort + private int managementPort; + + @Autowired + private TestRestTemplate testRestTemplate; + + @Test + void resourceShouldBeAvailableOnMainPort() { + ResponseEntity entity = this.testRestTemplate + .getForEntity("http://localhost:" + this.port + "/actuator/startup", String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + assertThat(entity.getBody()) + .contains("Java 8 date/time type `java.time.Clock$SystemClock` not supported by default"); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperTrueTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperTrueTests.java new file mode 100644 index 0000000000..57a084743e --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperTrueTests.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-2022 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 com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ContextConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration test for Jersey actuator when using an isolated {@link ObjectMapper}. + * + * @author Phillip Webb + */ +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, + properties = "management.endpoints.jackson.isolated-object-mapper=true") +@ContextConfiguration(loader = ApplicationStartupSpringBootContextLoader.class) +public class JerseyActuatorIsolatedObjectMapperTrueTests { + + @LocalServerPort + private int port; + + @LocalManagementPort + private int managementPort; + + @Autowired + private TestRestTemplate testRestTemplate; + + @Test + void resourceShouldBeAvailableOnMainPort() { + ResponseEntity entity = this.testRestTemplate + .getForEntity("http://localhost:" + this.port + "/actuator/startup", String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).contains("\"timeline\":"); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/main/java/smoketest/webflux/SampleWebFluxApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/main/java/smoketest/webflux/SampleWebFluxApplication.java index f31e090c01..d8e0e04cf3 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/main/java/smoketest/webflux/SampleWebFluxApplication.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/main/java/smoketest/webflux/SampleWebFluxApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 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 smoketest.webflux; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; import org.springframework.context.annotation.Bean; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.ServerResponse; @@ -29,7 +30,9 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.r public class SampleWebFluxApplication { public static void main(String[] args) { - SpringApplication.run(SampleWebFluxApplication.class, args); + SpringApplication application = new SpringApplication(SampleWebFluxApplication.class); + application.setApplicationStartup(new BufferingApplicationStartup(1024)); + application.run(args); } @Bean diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/main/resources/application.properties b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/main/resources/application.properties new file mode 100644 index 0000000000..641c39e657 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/main/resources/application.properties @@ -0,0 +1,3 @@ +management.endpoints.web.exposure.include=* +management.endpoints.jackson.isolated-object-mapper=true +spring.jackson.visibility.field=any diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/ApplicationStartupSpringBootContextLoader.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/ApplicationStartupSpringBootContextLoader.java new file mode 100644 index 0000000000..d6b13bbf8c --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/ApplicationStartupSpringBootContextLoader.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-2022 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.webflux; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; +import org.springframework.boot.test.context.SpringBootContextLoader; + +class ApplicationStartupSpringBootContextLoader extends SpringBootContextLoader { + + @Override + protected SpringApplication getSpringApplication() { + SpringApplication application = new SpringApplication(); + application.setApplicationStartup(new BufferingApplicationStartup(1024)); + return application; + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorDifferentPortTests.java similarity index 96% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorDifferentPortTests.java index d22383653c..74b09a6dda 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/WebFluxDifferentPortSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorDifferentPortTests.java @@ -34,7 +34,7 @@ import static org.assertj.core.api.Assertions.assertThat; */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { "management.server.port=0", "management.endpoints.web.base-path=/" }) -class WebFluxDifferentPortSampleActuatorApplicationTests { +class SampleWebFluxApplicationActuatorDifferentPortTests { @LocalManagementPort private int managementPort; diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorIsolatedObjectMapperFalseTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorIsolatedObjectMapperFalseTests.java new file mode 100644 index 0000000000..5db1210165 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorIsolatedObjectMapperFalseTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2022 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.webflux; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.web.reactive.server.WebTestClient; + +/** + * Integration test for WebFlux actuator when using an isolated {@link ObjectMapper}. + * + * @author Phillip Webb + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "management.endpoints.jackson.isolated-object-mapper=false") +@ContextConfiguration(loader = ApplicationStartupSpringBootContextLoader.class) +class SampleWebFluxApplicationActuatorIsolatedObjectMapperFalseTests { + + @Autowired + private WebTestClient webClient; + + @Test + void linksEndpointShouldBeAvailable() { + this.webClient.get().uri("/actuator/startup").accept(MediaType.APPLICATION_JSON).exchange().expectStatus() + .is5xxServerError(); + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorIsolatedObjectMapperTrueTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorIsolatedObjectMapperTrueTests.java new file mode 100644 index 0000000000..567d5703ec --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-webflux/src/test/java/smoketest/webflux/SampleWebFluxApplicationActuatorIsolatedObjectMapperTrueTests.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-2022 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.webflux; + +import java.nio.charset.StandardCharsets; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.web.reactive.server.EntityExchangeResult; +import org.springframework.test.web.reactive.server.WebTestClient; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration test for WebFlux actuator when not using an isolated {@link ObjectMapper}. + * + * @author Phillip Webb + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "management.endpoints.jackson.isolated-object-mapper=true") +@ContextConfiguration(loader = ApplicationStartupSpringBootContextLoader.class) +class SampleWebFluxApplicationActuatorIsolatedObjectMapperTrueTests { + + @Autowired + private WebTestClient webClient; + + @Test + void linksEndpointShouldBeAvailable() { + this.webClient.get().uri("/actuator/startup").accept(MediaType.APPLICATION_JSON).exchange().expectStatus() + .isOk().expectBody().consumeWith(this::assertExpectedJson); + } + + private void assertExpectedJson(EntityExchangeResult result) { + String body = new String(result.getResponseBody(), StandardCharsets.UTF_8); + assertThat(body).contains("\"timeline\":"); + } + +}