From 52825e7fea6799409393a211b8e239f64566bbe2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:25:04 +0100 Subject: [PATCH] build: bump org.springframework.boot:spring-boot-dependencies from 2.7.16 to 3.4.0 (#3898) * build: bump org.springframework.boot:spring-boot-dependencies Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 2.7.16 to 3.4.0. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.16...v3.4.0) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Update pom.xml * Update pom.xml * Update pom.xml * Add explicit okhttp dependency version * Prevent recursion when logging recursive advice bootstrapping * Support unwrapping webflux requests * Remove tests for TRACE option as it seems to be blocked by spring --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: jackshirazi Co-authored-by: Jonas Kunz --- .../elastic/apm/agent/bci/IndyBootstrap.java | 10 +++++++-- .../apm/agent/sdk/state/CallDepth.java | 4 ++++ .../apm-spring-restclient-test/pom.xml | 2 +- .../apm-spring-resttemplate-plugin/pom.xml | 3 ++- .../springwebflux/WebfluxServletHelper.java | 21 ++++++++++++------- .../AbstractServerInstrumentationTest.java | 8 +++---- apm-agent-plugins/apm-spring-webflux/pom.xml | 2 +- .../apm-spring-webmvc-plugin/pom.xml | 2 +- apm-agent-plugins/apm-spring-webmvc/pom.xml | 2 +- integration-tests/spring-boot-3/pom.xml | 2 +- 10 files changed, 36 insertions(+), 20 deletions(-) diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/IndyBootstrap.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/IndyBootstrap.java index 659a5b8c23..3380bc1b06 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/IndyBootstrap.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/IndyBootstrap.java @@ -219,6 +219,7 @@ public class IndyBootstrap { static Method bootstrapLoggingMethod; private static final CallDepth callDepth = CallDepth.get(IndyBootstrap.class); + private static final CallDepth loggingForNestedCall = CallDepth.get("indy-bootstrap-nested-logging"); private static Logger logger() { // must not be a static field as it would initialize logging before it's ready @@ -430,7 +431,12 @@ private static ConstantCallSite internalBootstrap(MethodHandles.Lookup lookup, S // avoid re-entrancy and stack overflow errors // may happen when bootstrapping an instrumentation that also gets triggered during the bootstrap // for example, adding correlation ids to the thread context when executing logger.debug. - logger().warn("Nested instrumented invokedynamic instruction linkage detected", new Throwable()); + if (!loggingForNestedCall.isNestedCallAndIncrement()) { + // We might be unlucky and cause an infinite recurison through logger() + // for this reason we have the loggingForNestedCall in place to prevent this recursion + logger().warn("Nested instrumented invokedynamic instruction linkage detected", new Throwable()); + } + loggingForNestedCall.decrement(); return null; } String adviceClassName = (String) args[0]; @@ -498,7 +504,7 @@ private static ConstantCallSite internalBootstrap(MethodHandles.Lookup lookup, S // When calling findStatic now, the lookup class will be one that is loaded by the plugin class loader MethodHandle methodHandle = indyLookup.findStatic(adviceInPluginCL, adviceMethodName, adviceMethodType); return new ConstantCallSite(methodHandle); - } catch (Exception e) { + } catch (Throwable e) { logger().error(e.getMessage(), e); return null; } finally { diff --git a/apm-agent-plugin-sdk/src/main/java/co/elastic/apm/agent/sdk/state/CallDepth.java b/apm-agent-plugin-sdk/src/main/java/co/elastic/apm/agent/sdk/state/CallDepth.java index 72e8129253..3dcf1e8545 100644 --- a/apm-agent-plugin-sdk/src/main/java/co/elastic/apm/agent/sdk/state/CallDepth.java +++ b/apm-agent-plugin-sdk/src/main/java/co/elastic/apm/agent/sdk/state/CallDepth.java @@ -43,6 +43,10 @@ private CallDepth() { public static CallDepth get(Class adviceClass) { // we want to return the same CallDepth instance even if the advice class has been loaded from different class loaders String key = adviceClass.getName(); + return get(key); + } + + public static CallDepth get(String key) { CallDepth callDepth = registry.get(key); if (callDepth == null) { registry.putIfAbsent(key, new CallDepth()); diff --git a/apm-agent-plugins/apm-spring-resttemplate/apm-spring-restclient-test/pom.xml b/apm-agent-plugins/apm-spring-resttemplate/apm-spring-restclient-test/pom.xml index 54c2583ea9..11190aca4c 100644 --- a/apm-agent-plugins/apm-spring-resttemplate/apm-spring-restclient-test/pom.xml +++ b/apm-agent-plugins/apm-spring-resttemplate/apm-spring-restclient-test/pom.xml @@ -20,7 +20,7 @@ org.springframework.boot spring-boot-dependencies - 3.3.4 + 3.4.0 pom import diff --git a/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/pom.xml b/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/pom.xml index 95def4b7e8..415ee0ce9f 100644 --- a/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/pom.xml +++ b/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/pom.xml @@ -23,7 +23,7 @@ org.springframework.boot spring-boot-dependencies - 3.3.4 + 3.4.0 pom import @@ -52,6 +52,7 @@ com.squareup.okhttp3 okhttp + ${version.okhttp} test diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxServletHelper.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxServletHelper.java index cc525a7f3a..3ee10c86d7 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxServletHelper.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxServletHelper.java @@ -18,12 +18,13 @@ */ package co.elastic.apm.agent.springwebflux; -import co.elastic.apm.agent.sdk.weakconcurrent.WeakKeySoftValueLoadingCache; -import co.elastic.apm.agent.tracer.Transaction; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; +import co.elastic.apm.agent.sdk.weakconcurrent.WeakKeySoftValueLoadingCache; +import co.elastic.apm.agent.tracer.Transaction; import org.springframework.http.server.reactive.AbstractServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpRequestDecorator; import org.springframework.web.server.ServerWebExchange; import javax.annotation.Nullable; @@ -60,19 +61,23 @@ public static Transaction getServletTransaction(ServerWebExchange exchange) { // While the active transaction is the one created by Servlet, it would rely on the fact that we are on the // same thread as the one that created the transaction, which is an implementation detail. - - Transaction transaction = null; - ServerHttpRequest exchangeRequest = exchange.getRequest(); + return getTransactionFromRequest(exchangeRequest); + } + + @Nullable + private static Transaction getTransactionFromRequest(ServerHttpRequest exchangeRequest) { if (exchangeRequest instanceof AbstractServerHttpRequest) { Object nativeRequest = ((AbstractServerHttpRequest) exchangeRequest).getNativeRequest(); // note: attribute name is defined in Servlet plugin and should be kept in sync - transaction = (Transaction) getServletAttribute(nativeRequest, "co.elastic.apm.agent.servlet.ServletApiAdvice.transaction"); + return (Transaction) getServletAttribute(nativeRequest, "co.elastic.apm.agent.servlet.ServletApiAdvice.transaction"); + } else if (exchangeRequest instanceof ServerHttpRequestDecorator) { + ServerHttpRequestDecorator decorator = (ServerHttpRequestDecorator) exchangeRequest; + return getTransactionFromRequest(decorator.getDelegate()); } - - return transaction; + return null; } /** diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/test/java/co/elastic/apm/agent/springwebflux/AbstractServerInstrumentationTest.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/test/java/co/elastic/apm/agent/springwebflux/AbstractServerInstrumentationTest.java index e27585baad..714171fc89 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/test/java/co/elastic/apm/agent/springwebflux/AbstractServerInstrumentationTest.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-spring5/src/test/java/co/elastic/apm/agent/springwebflux/AbstractServerInstrumentationTest.java @@ -19,16 +19,16 @@ package co.elastic.apm.agent.springwebflux; import co.elastic.apm.agent.AbstractInstrumentationTest; +import co.elastic.apm.agent.common.util.WildcardMatcher; import co.elastic.apm.agent.configuration.CoreConfigurationImpl; import co.elastic.apm.agent.impl.context.RequestImpl; import co.elastic.apm.agent.impl.context.UrlImpl; -import co.elastic.apm.agent.impl.transaction.TransactionImpl; -import co.elastic.apm.agent.tracer.configuration.WebConfiguration; import co.elastic.apm.agent.impl.error.ErrorCaptureImpl; -import co.elastic.apm.agent.common.util.WildcardMatcher; +import co.elastic.apm.agent.impl.transaction.TransactionImpl; import co.elastic.apm.agent.springwebflux.testapp.GreetingWebClient; import co.elastic.apm.agent.springwebflux.testapp.WebFluxApplication; import co.elastic.apm.agent.testutils.DisabledOnAppleSilicon; +import co.elastic.apm.agent.tracer.configuration.WebConfiguration; import co.elastic.apm.agent.tracer.metadata.PotentiallyMultiValuedMap; import org.assertj.core.data.Offset; import org.junit.jupiter.api.AfterAll; @@ -202,7 +202,7 @@ private Predicate expectClientError(int expectedStatus) { } @ParameterizedTest - @CsvSource({"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "TRACE"}) + @CsvSource({"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"}) void methodMapping(String method) { client.setHeader("Authorization", BASIC_AUTH_HEADER_VALUE); diff --git a/apm-agent-plugins/apm-spring-webflux/pom.xml b/apm-agent-plugins/apm-spring-webflux/pom.xml index bc44112394..fb79d1aeb1 100644 --- a/apm-agent-plugins/apm-spring-webflux/pom.xml +++ b/apm-agent-plugins/apm-spring-webflux/pom.xml @@ -18,7 +18,7 @@ 2.7.16 - 3.3.4 + 3.4.0 diff --git a/apm-agent-plugins/apm-spring-webmvc/apm-spring-webmvc-plugin/pom.xml b/apm-agent-plugins/apm-spring-webmvc/apm-spring-webmvc-plugin/pom.xml index f9bd1913a4..957d7c499f 100644 --- a/apm-agent-plugins/apm-spring-webmvc/apm-spring-webmvc-plugin/pom.xml +++ b/apm-agent-plugins/apm-spring-webmvc/apm-spring-webmvc-plugin/pom.xml @@ -22,7 +22,7 @@ org.springframework.boot spring-boot-dependencies - 3.3.4 + 3.4.0 pom import diff --git a/apm-agent-plugins/apm-spring-webmvc/pom.xml b/apm-agent-plugins/apm-spring-webmvc/pom.xml index a50c7f4787..cd6bb354ea 100644 --- a/apm-agent-plugins/apm-spring-webmvc/pom.xml +++ b/apm-agent-plugins/apm-spring-webmvc/pom.xml @@ -29,7 +29,7 @@ org.springframework.boot spring-boot-dependencies - 3.3.4 + 3.4.0 pom import diff --git a/integration-tests/spring-boot-3/pom.xml b/integration-tests/spring-boot-3/pom.xml index 0282518128..17417d1332 100644 --- a/integration-tests/spring-boot-3/pom.xml +++ b/integration-tests/spring-boot-3/pom.xml @@ -30,7 +30,7 @@ org.springframework.boot spring-boot-dependencies - 3.3.4 + 3.4.0 pom import