From 3346dbc7e55f1386b6e8cb853601270a8da4ce2c Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Wed, 2 Oct 2024 15:09:20 +0200 Subject: [PATCH] Replace GraphQlSourceBuilderCustomizer with directly providing a SentryInstrumentation bean if missing --- .../api/sentry-spring-boot-jakarta.api | 12 ++++- .../SentryGraphqlAutoConfiguration.java | 47 +++++++++++-------- sentry-spring-boot/api/sentry-spring-boot.api | 4 +- .../SentryGraphqlAutoConfiguration.java | 47 +++++++++++-------- .../api/sentry-spring-jakarta.api | 4 +- .../graphql/SentryGraphqlConfiguration.java | 38 +++++++++------ sentry-spring/api/sentry-spring.api | 4 +- .../graphql/SentryGraphqlConfiguration.java | 38 +++++++++------ 8 files changed, 118 insertions(+), 76 deletions(-) diff --git a/sentry-spring-boot-jakarta/api/sentry-spring-boot-jakarta.api b/sentry-spring-boot-jakarta/api/sentry-spring-boot-jakarta.api index 64af16aa0e..ac89da6d37 100644 --- a/sentry-spring-boot-jakarta/api/sentry-spring-boot-jakarta.api +++ b/sentry-spring-boot-jakarta/api/sentry-spring-boot-jakarta.api @@ -71,11 +71,19 @@ public class io/sentry/spring/boot/jakarta/SentryWebfluxAutoConfiguration { public fun sentryWebExceptionHandler (Lio/sentry/IScopes;)Lio/sentry/spring/jakarta/webflux/SentryWebExceptionHandler; } +public class io/sentry/spring/boot/jakarta/graphql/SentryGraphql22AutoConfiguration { + public fun ()V + public fun exceptionResolverAdapter ()Lio/sentry/spring/jakarta/graphql/SentryDataFetcherExceptionResolverAdapter; + public static fun graphqlBeanPostProcessor ()Lio/sentry/spring/jakarta/graphql/SentryGraphqlBeanPostProcessor; + public fun sentryInstrumentationWebMvc (Lio/sentry/spring/boot/jakarta/SentryProperties;Lorg/springframework/beans/factory/ObjectProvider;)Lio/sentry/graphql22/SentryInstrumentation; + public fun sentryInstrumentationWebflux (Lio/sentry/spring/boot/jakarta/SentryProperties;Lorg/springframework/beans/factory/ObjectProvider;)Lio/sentry/graphql22/SentryInstrumentation; +} + public class io/sentry/spring/boot/jakarta/graphql/SentryGraphqlAutoConfiguration { public fun ()V public fun exceptionResolverAdapter ()Lio/sentry/spring/jakarta/graphql/SentryDataFetcherExceptionResolverAdapter; public static fun graphqlBeanPostProcessor ()Lio/sentry/spring/jakarta/graphql/SentryGraphqlBeanPostProcessor; - public fun sourceBuilderCustomizerWebflux (Lio/sentry/spring/boot/jakarta/SentryProperties;)Lorg/springframework/boot/autoconfigure/graphql/GraphQlSourceBuilderCustomizer; - public fun sourceBuilderCustomizerWebmvc (Lio/sentry/spring/boot/jakarta/SentryProperties;)Lorg/springframework/boot/autoconfigure/graphql/GraphQlSourceBuilderCustomizer; + public fun sentryInstrumentationWebMvc (Lio/sentry/spring/boot/jakarta/SentryProperties;Lorg/springframework/beans/factory/ObjectProvider;)Lio/sentry/graphql/SentryInstrumentation; + public fun sentryInstrumentationWebflux (Lio/sentry/spring/boot/jakarta/SentryProperties;Lorg/springframework/beans/factory/ObjectProvider;)Lio/sentry/graphql/SentryInstrumentation; } diff --git a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/graphql/SentryGraphqlAutoConfiguration.java b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/graphql/SentryGraphqlAutoConfiguration.java index bd493e91d5..5f71bb54c5 100644 --- a/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/graphql/SentryGraphqlAutoConfiguration.java +++ b/sentry-spring-boot-jakarta/src/main/java/io/sentry/spring/boot/jakarta/graphql/SentryGraphqlAutoConfiguration.java @@ -2,14 +2,16 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.SentryIntegrationPackageStorage; +import io.sentry.graphql.SentryGraphqlInstrumentation; import io.sentry.graphql.SentryInstrumentation; import io.sentry.spring.boot.jakarta.SentryProperties; import io.sentry.spring.jakarta.graphql.SentryDataFetcherExceptionResolverAdapter; import io.sentry.spring.jakarta.graphql.SentryGraphqlBeanPostProcessor; import io.sentry.spring.jakarta.graphql.SentrySpringSubscriptionHandler; import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -19,37 +21,42 @@ @Open public class SentryGraphqlAutoConfiguration { - @Bean + @Bean(name = "sentryInstrumentation") + @ConditionalOnMissingBean(name = "sentryInstrumentation") @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) - public GraphQlSourceBuilderCustomizer sourceBuilderCustomizerWebmvc( - final @NotNull SentryProperties sentryProperties) { + public SentryInstrumentation sentryInstrumentationWebMvc( + final @NotNull SentryProperties sentryProperties, + final @NotNull ObjectProvider + beforeSpanCallback) { SentryIntegrationPackageStorage.getInstance().addIntegration("Spring6GrahQLWebMVC"); - return sourceBuilderCustomizer(sentryProperties, false); + return createInstrumentation(sentryProperties, beforeSpanCallback, false); } - @Bean + @Bean(name = "sentryInstrumentation") + @ConditionalOnMissingBean(name = "sentryInstrumentation") @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) - public GraphQlSourceBuilderCustomizer sourceBuilderCustomizerWebflux( - final @NotNull SentryProperties sentryProperties) { + public SentryInstrumentation sentryInstrumentationWebflux( + final @NotNull SentryProperties sentryProperties, + final @NotNull ObjectProvider + beforeSpanCallback) { SentryIntegrationPackageStorage.getInstance().addIntegration("Spring6GrahQLWebFlux"); - return sourceBuilderCustomizer(sentryProperties, true); + return createInstrumentation(sentryProperties, beforeSpanCallback, true); } /** * We're not setting defaultDataFetcherExceptionHandler here on purpose and instead use the * resolver adapter below. This way Springs handler can still forward to other resolver adapters. */ - private GraphQlSourceBuilderCustomizer sourceBuilderCustomizer( - final @NotNull SentryProperties sentryProperties, final boolean captureRequestBody) { - return (builder) -> - builder.configureGraphQl( - graphQlBuilder -> - graphQlBuilder.instrumentation( - new SentryInstrumentation( - null, - new SentrySpringSubscriptionHandler(), - captureRequestBody, - sentryProperties.getGraphql().getIgnoredErrorTypes()))); + private SentryInstrumentation createInstrumentation( + final @NotNull SentryProperties sentryProperties, + final @NotNull ObjectProvider + beforeSpanCallback, + final boolean captureRequestBody) { + return new SentryInstrumentation( + beforeSpanCallback.getIfAvailable(), + new SentrySpringSubscriptionHandler(), + captureRequestBody, + sentryProperties.getGraphql().getIgnoredErrorTypes()); } @Bean diff --git a/sentry-spring-boot/api/sentry-spring-boot.api b/sentry-spring-boot/api/sentry-spring-boot.api index bc03b89d6a..79b72bfb39 100644 --- a/sentry-spring-boot/api/sentry-spring-boot.api +++ b/sentry-spring-boot/api/sentry-spring-boot.api @@ -67,7 +67,7 @@ public class io/sentry/spring/boot/graphql/SentryGraphqlAutoConfiguration { public fun ()V public fun exceptionResolverAdapter ()Lio/sentry/spring/graphql/SentryDataFetcherExceptionResolverAdapter; public static fun graphqlBeanPostProcessor ()Lio/sentry/spring/graphql/SentryGraphqlBeanPostProcessor; - public fun sourceBuilderCustomizerWebflux (Lio/sentry/spring/boot/SentryProperties;)Lorg/springframework/boot/autoconfigure/graphql/GraphQlSourceBuilderCustomizer; - public fun sourceBuilderCustomizerWebmvc (Lio/sentry/spring/boot/SentryProperties;)Lorg/springframework/boot/autoconfigure/graphql/GraphQlSourceBuilderCustomizer; + public fun sentryInstrumentationWebMvc (Lio/sentry/spring/boot/SentryProperties;Lorg/springframework/beans/factory/ObjectProvider;)Lio/sentry/graphql/SentryInstrumentation; + public fun sentryInstrumentationWebflux (Lio/sentry/spring/boot/SentryProperties;Lorg/springframework/beans/factory/ObjectProvider;)Lio/sentry/graphql/SentryInstrumentation; } diff --git a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/graphql/SentryGraphqlAutoConfiguration.java b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/graphql/SentryGraphqlAutoConfiguration.java index ab025b2ed1..3fcb1cee4b 100644 --- a/sentry-spring-boot/src/main/java/io/sentry/spring/boot/graphql/SentryGraphqlAutoConfiguration.java +++ b/sentry-spring-boot/src/main/java/io/sentry/spring/boot/graphql/SentryGraphqlAutoConfiguration.java @@ -2,14 +2,16 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.SentryIntegrationPackageStorage; +import io.sentry.graphql.SentryGraphqlInstrumentation; import io.sentry.graphql.SentryInstrumentation; import io.sentry.spring.boot.SentryProperties; import io.sentry.spring.graphql.SentryDataFetcherExceptionResolverAdapter; import io.sentry.spring.graphql.SentryGraphqlBeanPostProcessor; import io.sentry.spring.graphql.SentrySpringSubscriptionHandler; import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -19,37 +21,42 @@ @Open public class SentryGraphqlAutoConfiguration { - @Bean + @Bean(name = "sentryInstrumentation") + @ConditionalOnMissingBean(name = "sentryInstrumentation") @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) - public GraphQlSourceBuilderCustomizer sourceBuilderCustomizerWebmvc( - final @NotNull SentryProperties sentryProperties) { + public SentryInstrumentation sentryInstrumentationWebMvc( + final @NotNull SentryProperties sentryProperties, + final @NotNull ObjectProvider + beforeSpanCallback) { SentryIntegrationPackageStorage.getInstance().addIntegration("Spring5GrahQLWebMVC"); - return sourceBuilderCustomizer(sentryProperties, false); + return createInstrumentation(sentryProperties, beforeSpanCallback, false); } - @Bean + @Bean(name = "sentryInstrumentation") + @ConditionalOnMissingBean(name = "sentryInstrumentation") @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) - public GraphQlSourceBuilderCustomizer sourceBuilderCustomizerWebflux( - final @NotNull SentryProperties sentryProperties) { + public SentryInstrumentation sentryInstrumentationWebflux( + final @NotNull SentryProperties sentryProperties, + final @NotNull ObjectProvider + beforeSpanCallback) { SentryIntegrationPackageStorage.getInstance().addIntegration("Spring5GrahQLWebFlux"); - return sourceBuilderCustomizer(sentryProperties, true); + return createInstrumentation(sentryProperties, beforeSpanCallback, true); } /** * We're not setting defaultDataFetcherExceptionHandler here on purpose and instead use the * resolver adapter below. This way Springs handler can still forward to other resolver adapters. */ - private GraphQlSourceBuilderCustomizer sourceBuilderCustomizer( - final @NotNull SentryProperties sentryProperties, final boolean captureRequestBody) { - return (builder) -> - builder.configureGraphQl( - graphQlBuilder -> - graphQlBuilder.instrumentation( - new SentryInstrumentation( - null, - new SentrySpringSubscriptionHandler(), - captureRequestBody, - sentryProperties.getGraphql().getIgnoredErrorTypes()))); + private SentryInstrumentation createInstrumentation( + final @NotNull SentryProperties sentryProperties, + final @NotNull ObjectProvider + beforeSpanCallback, + final boolean captureRequestBody) { + return new SentryInstrumentation( + beforeSpanCallback.getIfAvailable(), + new SentrySpringSubscriptionHandler(), + captureRequestBody, + sentryProperties.getGraphql().getIgnoredErrorTypes()); } @Bean diff --git a/sentry-spring-jakarta/api/sentry-spring-jakarta.api b/sentry-spring-jakarta/api/sentry-spring-jakarta.api index 2897189677..825839e75f 100644 --- a/sentry-spring-jakarta/api/sentry-spring-jakarta.api +++ b/sentry-spring-jakarta/api/sentry-spring-jakarta.api @@ -185,8 +185,8 @@ public class io/sentry/spring/jakarta/graphql/SentryGraphqlConfiguration { public fun ()V public fun exceptionResolverAdapter ()Lio/sentry/spring/jakarta/graphql/SentryDataFetcherExceptionResolverAdapter; public fun graphqlBeanPostProcessor ()Lio/sentry/spring/jakarta/graphql/SentryGraphqlBeanPostProcessor; - public fun sourceBuilderCustomizerWebflux ()Lorg/springframework/boot/autoconfigure/graphql/GraphQlSourceBuilderCustomizer; - public fun sourceBuilderCustomizerWebmvc ()Lorg/springframework/boot/autoconfigure/graphql/GraphQlSourceBuilderCustomizer; + public fun sentryInstrumentationWebMvc (Lorg/springframework/beans/factory/ObjectProvider;)Lio/sentry/graphql/SentryInstrumentation; + public fun sentryInstrumentationWebflux (Lorg/springframework/beans/factory/ObjectProvider;)Lio/sentry/graphql/SentryInstrumentation; } public final class io/sentry/spring/jakarta/graphql/SentrySpringSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { diff --git a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryGraphqlConfiguration.java b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryGraphqlConfiguration.java index 9d8224e88c..da83c89349 100644 --- a/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryGraphqlConfiguration.java +++ b/sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/graphql/SentryGraphqlConfiguration.java @@ -2,9 +2,12 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.SentryIntegrationPackageStorage; +import io.sentry.graphql.SentryGraphqlInstrumentation; import io.sentry.graphql.SentryInstrumentation; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -14,31 +17,38 @@ @Open public class SentryGraphqlConfiguration { - @Bean + @Bean(name = "sentryInstrumentation") + @ConditionalOnMissingBean(name = "sentryInstrumentation") @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) - public GraphQlSourceBuilderCustomizer sourceBuilderCustomizerWebmvc() { + public SentryInstrumentation sentryInstrumentationWebMvc( + final @NotNull ObjectProvider + beforeSpanCallback) { SentryIntegrationPackageStorage.getInstance().addIntegration("Spring6GrahQLWebMVC"); - return sourceBuilderCustomizer(false); + return createInstrumentation(beforeSpanCallback, false); } - @Bean + @Bean(name = "sentryInstrumentation") + @ConditionalOnMissingBean(name = "sentryInstrumentation") @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) - public GraphQlSourceBuilderCustomizer sourceBuilderCustomizerWebflux() { + public SentryInstrumentation sentryInstrumentationWebflux( + final @NotNull ObjectProvider + beforeSpanCallback) { SentryIntegrationPackageStorage.getInstance().addIntegration("Spring6GrahQLWebFlux"); - return sourceBuilderCustomizer(true); + return createInstrumentation(beforeSpanCallback, true); } /** * We're not setting defaultDataFetcherExceptionHandler here on purpose and instead use the * resolver adapter below. This way Springs handler can still forward to other resolver adapters. */ - private GraphQlSourceBuilderCustomizer sourceBuilderCustomizer(final boolean captureRequestBody) { - return (builder) -> - builder.configureGraphQl( - graphQlBuilder -> - graphQlBuilder.instrumentation( - new SentryInstrumentation( - null, new SentrySpringSubscriptionHandler(), captureRequestBody))); + private SentryInstrumentation createInstrumentation( + final @NotNull ObjectProvider + beforeSpanCallback, + final boolean captureRequestBody) { + return new SentryInstrumentation( + beforeSpanCallback.getIfAvailable(), + new SentrySpringSubscriptionHandler(), + captureRequestBody); } @Bean diff --git a/sentry-spring/api/sentry-spring.api b/sentry-spring/api/sentry-spring.api index 2b5bbd98c1..84b9ddd133 100644 --- a/sentry-spring/api/sentry-spring.api +++ b/sentry-spring/api/sentry-spring.api @@ -185,8 +185,8 @@ public class io/sentry/spring/graphql/SentryGraphqlConfiguration { public fun ()V public fun exceptionResolverAdapter ()Lio/sentry/spring/graphql/SentryDataFetcherExceptionResolverAdapter; public fun graphqlBeanPostProcessor ()Lio/sentry/spring/graphql/SentryGraphqlBeanPostProcessor; - public fun sourceBuilderCustomizerWebflux ()Lorg/springframework/boot/autoconfigure/graphql/GraphQlSourceBuilderCustomizer; - public fun sourceBuilderCustomizerWebmvc ()Lorg/springframework/boot/autoconfigure/graphql/GraphQlSourceBuilderCustomizer; + public fun sentryInstrumentationWebMvc (Lorg/springframework/beans/factory/ObjectProvider;)Lio/sentry/graphql/SentryInstrumentation; + public fun sentryInstrumentationWebflux (Lorg/springframework/beans/factory/ObjectProvider;)Lio/sentry/graphql/SentryInstrumentation; } public final class io/sentry/spring/graphql/SentrySpringSubscriptionHandler : io/sentry/graphql/SentrySubscriptionHandler { diff --git a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryGraphqlConfiguration.java b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryGraphqlConfiguration.java index b938e6817d..97b8d765d7 100644 --- a/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryGraphqlConfiguration.java +++ b/sentry-spring/src/main/java/io/sentry/spring/graphql/SentryGraphqlConfiguration.java @@ -2,9 +2,12 @@ import com.jakewharton.nopen.annotation.Open; import io.sentry.SentryIntegrationPackageStorage; +import io.sentry.graphql.SentryGraphqlInstrumentation; import io.sentry.graphql.SentryInstrumentation; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -14,31 +17,38 @@ @Open public class SentryGraphqlConfiguration { - @Bean + @Bean(name = "sentryInstrumentation") + @ConditionalOnMissingBean(name = "sentryInstrumentation") @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) - public GraphQlSourceBuilderCustomizer sourceBuilderCustomizerWebmvc() { + public SentryInstrumentation sentryInstrumentationWebMvc( + final @NotNull ObjectProvider + beforeSpanCallback) { SentryIntegrationPackageStorage.getInstance().addIntegration("Spring5GrahQLWebMVC"); - return sourceBuilderCustomizer(false); + return createInstrumentation(beforeSpanCallback, false); } - @Bean + @Bean(name = "sentryInstrumentation") + @ConditionalOnMissingBean(name = "sentryInstrumentation") @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) - public GraphQlSourceBuilderCustomizer sourceBuilderCustomizerWebflux() { + public SentryInstrumentation sentryInstrumentationWebflux( + final @NotNull ObjectProvider + beforeSpanCallback) { SentryIntegrationPackageStorage.getInstance().addIntegration("Spring5GrahQLWebFlux"); - return sourceBuilderCustomizer(true); + return createInstrumentation(beforeSpanCallback, true); } /** * We're not setting defaultDataFetcherExceptionHandler here on purpose and instead use the * resolver adapter below. This way Springs handler can still forward to other resolver adapters. */ - private GraphQlSourceBuilderCustomizer sourceBuilderCustomizer(final boolean captureRequestBody) { - return (builder) -> - builder.configureGraphQl( - graphQlBuilder -> - graphQlBuilder.instrumentation( - new SentryInstrumentation( - null, new SentrySpringSubscriptionHandler(), captureRequestBody))); + private SentryInstrumentation createInstrumentation( + final @NotNull ObjectProvider + beforeSpanCallback, + final boolean captureRequestBody) { + return new SentryInstrumentation( + beforeSpanCallback.getIfAvailable(), + new SentrySpringSubscriptionHandler(), + captureRequestBody); } @Bean