diff --git a/CHANGELOG.next-release.md b/CHANGELOG.next-release.md index f8987acd138..739d800f1b9 100644 --- a/CHANGELOG.next-release.md +++ b/CHANGELOG.next-release.md @@ -15,7 +15,7 @@ This file contains all changes which are not released yet. # Features and enhancements - +* Add experimental support for Spring Boot 4 / Spring Framework 7 in WebFlux instrumentation # Deprecations diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webclient-plugin/src/main/java/co/elastic/apm/agent/springwebclient/ClientRequestHeaderGetter.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webclient-plugin/src/main/java/co/elastic/apm/agent/springwebclient/ClientRequestHeaderGetter.java index ed164348163..27151b4cbe5 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webclient-plugin/src/main/java/co/elastic/apm/agent/springwebclient/ClientRequestHeaderGetter.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webclient-plugin/src/main/java/co/elastic/apm/agent/springwebclient/ClientRequestHeaderGetter.java @@ -36,10 +36,7 @@ public String getFirstHeader(String headerName, ClientRequest carrier) { @Override public void forEach(String headerName, ClientRequest carrier, S state, HeaderConsumer consumer) { - List headerValues = carrier.headers().get(headerName); - if (headerValues == null) { - return; - } + List headerValues = carrier.headers().getValuesAsList(headerName); for (String value : headerValues) { consumer.accept(value, state); } diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml index e143c575846..341fe3d506c 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml @@ -77,6 +77,12 @@ test test-jar + + + org.apache.ivy + ivy + test + diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/DispatcherHandlerInstrumentation.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/DispatcherHandlerInstrumentation.java index 8db425e4757..85cecc032a7 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/DispatcherHandlerInstrumentation.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/DispatcherHandlerInstrumentation.java @@ -61,8 +61,8 @@ public static class HandleAdvice { @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) public static Object onEnter(@Advice.Argument(0) ServerWebExchange exchange) { - List upgradeHeader = exchange.getRequest().getHeaders().get("upgrade"); - if (upgradeHeader != null && upgradeHeader.contains("websocket")) { + List upgradeHeader = exchange.getRequest().getHeaders().getValuesAsList("upgrade"); + if (upgradeHeader.contains("websocket")) { // just ignore upgrade WS upgrade requests for now return null; } diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/HeaderGetter.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/HeaderGetter.java index e4e146d691b..ecf84950059 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/HeaderGetter.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/HeaderGetter.java @@ -34,10 +34,7 @@ public String getFirstHeader(String headerName, HttpHeaders carrier) { @Override public void forEach(String headerName, HttpHeaders carrier, S state, HeaderConsumer consumer) { - List values = carrier.get(headerName); - if (values == null) { - return; - } + List values = carrier.getValuesAsList(headerName); for (int i = 0; i < values.size(); i++) { consumer.accept(values.get(i), state); } diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/test/java/co/elastic/apm/agent/springwebflux/HeaderGetterTest.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/test/java/co/elastic/apm/agent/springwebflux/HeaderGetterTest.java index bb1896c6f42..3e078a4b610 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/test/java/co/elastic/apm/agent/springwebflux/HeaderGetterTest.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/test/java/co/elastic/apm/agent/springwebflux/HeaderGetterTest.java @@ -34,7 +34,7 @@ protected HeaderGetter createTextHeaderGetter() { @Override protected HttpHeaders createCarrier(Map> map) { HttpHeaders headers = new HttpHeaders(); - map.forEach(headers::put); + map.forEach(headers::addAll); return headers; } diff --git a/docs/reference/supported-technologies.md b/docs/reference/supported-technologies.md index 8da199b4e43..de0d4fe1acd 100644 --- a/docs/reference/supported-technologies.md +++ b/docs/reference/supported-technologies.md @@ -81,7 +81,7 @@ As this message states, you can disable this check if required by adding `-Delas |-----------------------------------|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------| | Servlet API | ≥ 3.x, ≤ 6.x | A transaction will be created for all incoming HTTP requests to your Servlet API-based application. Starting in version 1.18.0, additional spans are created if the servlet dispatches execution to another servlet through the `forward` or `include` APIs, or to an error page. See also [Application Servers/Servlet Containers](#supported-app-servers) | 1.0.0, 4.0+ (`jakarta.servlet`) since 1.28.0 | | Spring Web MVC | ≥ 4.x, ≤ 6.x; (7.x experimental) | If you are using Spring MVC (for example with Spring Boot), the transactions are named based on your controllers (`ControllerClass#controllerMethod`). | 1.0.0, 6.x since 1.38.0 | -| Spring Webflux | ≥ 5.2.3, ≤ 6.x | Creates transactions for incoming HTTP requests, supports annotated and functional endpoints. | 1.24.0 (experimental), 1.34.0 (GA), 6.1+ since 1.45.0 | +| Spring Webflux | ≥ 5.2.3, ≤ 6.x; (7.x experimental) | Creates transactions for incoming HTTP requests, supports annotated and functional endpoints. | 1.24.0 (experimental), 1.34.0 (GA), 6.1+ since 1.45.0 | | JavaServer Faces | ≥ 2.2.x, ≤ 3.0.0 | If you are using JSF, transactions are named based on the requested Facelets and spans are captured for visibility into execution andrendering | 1.0.0, `jakarta.faces` since 1.28.0 | | Spring Boot | ≥ 1.5.x, ≤ 3.x; (4.x experimental) | Supports embedded Tomcat, Jetty and Undertow | 1.0.0, 3.x since 1.38.0 | | JAX-RS | ≥ 2.x, ≤ 3.x | The transactions are named based on your resources (`ResourceClass#resourceMethod`). Note that only the packages configured in [`application_packages`](/reference/config-stacktrace.md#config-application-packages) are scanned for JAX-RS resources. If you don’t set this option, all classes are scanned. This comes at the cost of increased startup times, however.
Note: JAX-RS is only supported when running on a supported [Application Server/Servlet Container](#supported-app-servers). | 1.0.0, `jakarta.ws.rs` since 1.28.0 |