From fe43f881c124e9100d5919bd3f9ed1589d0db4e1 Mon Sep 17 00:00:00 2001 From: Corneil du Plessis Date: Wed, 18 Dec 2024 16:13:47 +0200 Subject: [PATCH] Fix problem with BeanPostProcessing (#1447) Change endpoint mapping from BeanPostProcessor to SmartInitializingSingleton Added Test and updated test.sh to invoke with separate profile. Fixes #1435 --- ci/test.sh | 1 + spring-ws-core/pom.xml | 109 ++++++++++++++++++ .../AnnotationActionEndpointMapping.java | 21 +--- .../ObservationInWsConfigurerTests.java | 74 ++++++++++++ 4 files changed, 190 insertions(+), 15 deletions(-) create mode 100644 spring-ws-core/src/test/java/org/springframework/ws/observation/ObservationInWsConfigurerTests.java diff --git a/ci/test.sh b/ci/test.sh index 28a0dce2..fe82b829 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -9,3 +9,4 @@ MAVEN_OPTS="-Duser.name=spring-builds+jenkins -Duser.home=/tmp/jenkins-home" \ MAVEN_OPTS="-Duser.name=spring-builds+jenkins -Duser.home=/tmp/jenkins-home" \ ./mvnw -s settings.xml \ -P-default,${PROFILE},observation clean dependency:list test -Dsort -B -U + diff --git a/spring-ws-core/pom.xml b/spring-ws-core/pom.xml index 16998873..eb55591d 100644 --- a/spring-ws-core/pom.xml +++ b/spring-ws-core/pom.xml @@ -248,6 +248,115 @@ + + default + + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + + **/ObservationInWsConfigurerTests.* + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.2 + + + **/ObservationInWsConfigurerTests.* + + + + + + + + observation + + 3.2.12 + + + + + org.springframework.boot + spring-boot-dependencies + pom + import + ${spring-boot.version} + + + + + + io.micrometer + micrometer-tracing-bridge-brave + 1.3.4 + test + + + org.springframework.boot + spring-boot-starter-web + test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-actuator + test + + + org.assertj + assertj-core + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + + **/wsdl/**/* + + + **/ObservationInWsConfigurerTests.* + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.2 + + true + + + spring-boot.run.profiles + observation + + + + **/ObservationInWsConfigurerTests.java + + + + + + docs diff --git a/spring-ws-core/src/main/java/org/springframework/ws/soap/addressing/server/AnnotationActionEndpointMapping.java b/spring-ws-core/src/main/java/org/springframework/ws/soap/addressing/server/AnnotationActionEndpointMapping.java index 465af85d..f9905c5c 100644 --- a/spring-ws-core/src/main/java/org/springframework/ws/soap/addressing/server/AnnotationActionEndpointMapping.java +++ b/spring-ws-core/src/main/java/org/springframework/ws/soap/addressing/server/AnnotationActionEndpointMapping.java @@ -21,9 +21,7 @@ import java.lang.reflect.Method; import java.net.URI; import java.net.URISyntaxException; -import org.springframework.aop.support.AopUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.StringUtils; import org.springframework.ws.server.endpoint.MethodEndpoint; @@ -54,11 +52,12 @@ import org.springframework.ws.soap.addressing.server.annotation.Address; * incoming message. * * @author Arjen Poutsma + * @author Corneil du Plessis (with thanks to Chris Bono) * @see Action * @see Address * @since 1.5.0 */ -public class AnnotationActionEndpointMapping extends AbstractActionMethodEndpointMapping implements BeanPostProcessor { +public class AnnotationActionEndpointMapping extends AbstractActionMethodEndpointMapping implements SmartInitializingSingleton { /** Returns the 'endpoint' annotation type. Default is {@link Endpoint}. */ protected Class getEndpointAnnotationType() { @@ -133,16 +132,8 @@ public class AnnotationActionEndpointMapping extends AbstractActionMethodEndpoin } } - @Override - public final Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - return bean; - } - - @Override - public final Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (AopUtils.getTargetClass(bean).getAnnotation(getEndpointAnnotationType()) != null) { - registerMethods(bean); - } - return bean; + public void afterSingletonsInstantiated() { + this.getApplicationContext().getBeansWithAnnotation(this.getEndpointAnnotationType()) + .values().forEach(this::registerMethods); } } diff --git a/spring-ws-core/src/test/java/org/springframework/ws/observation/ObservationInWsConfigurerTests.java b/spring-ws-core/src/test/java/org/springframework/ws/observation/ObservationInWsConfigurerTests.java new file mode 100644 index 00000000..5d0a8b25 --- /dev/null +++ b/spring-ws-core/src/test/java/org/springframework/ws/observation/ObservationInWsConfigurerTests.java @@ -0,0 +1,74 @@ +package org.springframework.ws.observation; + +import io.micrometer.observation.ObservationRegistry; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Profile; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.ws.config.annotation.WsConfigurerAdapter; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * This test is executed by using observation Maven profile and explicitly excluding the default profile. + * This test relies on dependencies that cause problems with other tests in Spring WS Core. + * @author Corneil du Plessis + */ +@Profile("observation") +@SpringBootTest(classes = ObservationInWsConfigurerTests.WsTracingApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ObservationInWsConfigurerTests { + @LocalServerPort + private int port; + + @Autowired + private TestRestTemplate restTemplate; + + @Test + void responseShouldNotBeEmpty() { + final ResponseEntity response = + restTemplate.getForEntity("http://localhost:" + port + "/test", String.class); + assertThat(response.getBody()).isNotEmpty(); + } + + @RestController + public static class TestEndpoint { + private static final Logger log = LoggerFactory.getLogger(TestEndpoint.class); + + @GetMapping("/test") + public String test() { + log.info("test"); + return MDC.get("spanId"); + } + } + + @Configuration + public static class WsConfig extends WsConfigurerAdapter { + private final ObservationRegistry observationRegistry; + + public WsConfig(ObservationRegistry observationRegistry) { + this.observationRegistry = observationRegistry; + } + } + + @SpringBootApplication + @Import(WsConfig.class) + public static class WsTracingApplication { + public static void main(String[] args) { + SpringApplication.run(WsTracingApplication.class, args); + } + + } +}